在 pandas 数据框中展开时间序列数据

Expand time series data in pandas dataframe

我正在尝试在 pandas 数据帧中的所有数据的时间点之间进行插值。我当前的数据是按 0.04 秒的时间增量计算的。我希望它以 0.01 秒的增量来匹配另一个数据集。我意识到我可以使用 DataFrame.interpolate() 函数来执行此操作。但是,我一直在研究如何以有效的方式在我的数据帧的每一行之间插入 3 行 NaN。

import pandas as pd
import numpy as np

df = pd.DataFrame(data={"Time": [0.0, 0.04, 0.08, 0.12], 
                        "Pulse": [76, 74, 77, 80],
                        "O2":[99, 100, 99, 98]})
df_ins = pd.DataFrame(data={"Time": [np.nan, np.nan, np.nan], 
                            "Pulse": [np.nan, np.nan, np.nan],
                            "O2":[np.nan, np.nan, np.nan]})

我要df从这个改造:

    Time    Pulse   O2
0   0.00    76      99
1   0.04    74      100
2   0.08    77      99
3   0.12    80      98

像这样:

    Time    Pulse   O2
0   0.00    76      99
1   NaN     NaN     NaN
2   NaN     NaN     NaN
3   NaN     NaN     NaN
4   0.04    74      100
5   NaN     NaN     NaN
6   NaN     NaN     NaN
7   NaN     NaN     NaN
8   0.08    77      99
9   NaN     NaN     NaN
10  NaN     NaN     NaN
11  NaN     NaN     NaN
12  0.12    80      98

然后我可以调用

df = df.interpolate()

这会产生这样的结果(我在这里编造数字):

    Time    Pulse   O2
0   0.00    76      99
1   0.01    76      99
2   0.02    75      99
3   0.03    74      100
4   0.04    74      100
5   0.05    75      100
6   0.06    76      99
7   0.07    77      99
8   0.08    77      99
9   0.09    77      99
10  0.10    78      98
11  0.11    79      98
12  0.12    80      98

我试图通过在每一行之后插入 df_ins 框架来使用 iterrows 技术。但是我的索引在迭代过程中被丢弃了。我还尝试切片 df 并连接 df 切片和 df_ins,但索引再次被循环丢弃。

有人对如何有效地执行此操作有任何建议吗?

我相信使用 np.linspace 和按列处理应该比插值更快(如果您的时间列不完全采用时间格式):

import numpy as np
import pandas as pd

new_dict = {}
for c in df.columns:
    arr = df[c]
    ret = []
    for i in range(1, len(arr)):
        ret.append(np.linspace(arr[i-1], arr[i], 4, endpoint=False)[1:])
    new_dict[c] = np.concatenate(ret)
pd.concat([df, pd.DataFrame(new_dict)]).sort_values('Time').reset_index(drop=True)
    Time    Pulse   O2
0   0.00    76.00   99.00
1   0.01    75.50   99.25
2   0.02    75.00   99.50
3   0.03    74.50   99.75
4   0.04    74.00   100.00
5   0.05    74.75   99.75
6   0.06    75.50   99.50
7   0.07    76.25   99.25
8   0.08    77.00   99.00
9   0.09    77.75   98.75
10  0.10    78.50   98.50
11  0.11    79.25   98.25
12  0.12    80.00   98.00

在此处使用 resample(将 ffill 替换为您想要的行为,也许会乱用 interpolate

df["Time"] = pd.to_timedelta(df["Time"], unit="S")
df.set_index("Time").resample("0.01S").ffill()

                 Pulse   O2
Time
00:00:00            76   99
00:00:00.010000     76   99
00:00:00.020000     76   99
00:00:00.030000     76   99
00:00:00.040000     74  100
00:00:00.050000     74  100
00:00:00.060000     74  100
00:00:00.070000     74  100
00:00:00.080000     77   99
00:00:00.090000     77   99
00:00:00.100000     77   99
00:00:00.110000     77   99
00:00:00.120000     80   98

如果您想要插值:

df.set_index("Time").resample("0.01S").interpolate()

                 Pulse      O2
Time
00:00:00         76.00   99.00
00:00:00.010000  75.50   99.25
00:00:00.020000  75.00   99.50
00:00:00.030000  74.50   99.75
00:00:00.040000  74.00  100.00
00:00:00.050000  74.75   99.75
00:00:00.060000  75.50   99.50
00:00:00.070000  76.25   99.25
00:00:00.080000  77.00   99.00
00:00:00.090000  77.75   98.75
00:00:00.100000  78.50   98.50
00:00:00.110000  79.25   98.25
00:00:00.120000  80.00   98.00