缺少时间值的平均时间序列

Average time series with missing time value

我有两个系列日期集,像这样读入 pandas(第一列是行索引,第二列是时间,第三列是通量)。

data1:
0  1977.262917  0.965209  
1  1977.283350  0.969835  
2  1977.303782  0.970732  
3  1977.365079  0.948716  
4  1977.405944  0.945410  

data2:
0  1977.262918  0.922487  
1  1977.283350  0.925750  
2  1977.303783  0.922952  
3  1977.365080  0.907151  
4  1977.385512  0.891967

我需要根据时间对这两个数据集的流量和时间进行平均。但是,如您所见,时间未对齐。其中一些失踪了。它们大致相隔 0.02。我正在考虑根据起点将所有时间列重新采样为统一分隔的列。我想要这样的东西。

data1:
0  1977.262917  0.965209  
1  1977.282917  0.969835  
2  1977.302917  0.970732  
3  1977.322917  nan  
4  1977.342917  nan  
5  1977.362917  0.948716  
6  1977.382917  nan  
7  1977.402917  0.945410  


data2:
0  1977.262918  0.922487  
1  1977.282918  0.925750  
2  1977.302918  0.922952  
3  1977.322918  nan  
4  1977.342918  nan  
5  1977.362918  0.907151  
6  1977.382918  0.891967  
7  1977.402918  nan  

然后用nan后面或者前面的那个填充。通过这种方式,我可以直接对两个数据集进行平均,因为现在它们大致对齐了。那么我怎样才能在 python 中使用 pandas 或 numpy、scipy 等实现这一点。或者是否有更好的方法(除了我正在考虑的方式)来完成这项工作?也许插值?谢谢大家。

IIUC 你用 interpolate 方法做到这一点 method 参数等于 linear 做线性插值或者 nearest 如果你想用关闭重采样数据框的值:

In [459]: df
Out[459]: 
             0         1
0  1977.262917  0.965209
1  1977.282917  0.969835
2  1977.302917  0.970732
3  1977.322917       NaN
4  1977.342917       NaN
5  1977.362917  0.948716
6  1977.382917       NaN
7  1977.402917  0.945410

In [460]: df.interpolate(method='linear')
Out[460]: 
             0         1
0  1977.262917  0.965209
1  1977.282917  0.969835
2  1977.302917  0.970732
3  1977.322917  0.963393
4  1977.342917  0.956055
5  1977.362917  0.948716
6  1977.382917  0.947063
7  1977.402917  0.945410

In [462]: df.interpolate(method='nearest')
Out[462]: 
             0         1
0  1977.262917  0.965209
1  1977.282917  0.969835
2  1977.302917  0.970732
3  1977.322917  0.970732
4  1977.342917  0.948716
5  1977.362917  0.948716
6  1977.382917  0.948716
7  1977.402917  0.945410

编辑

对于您的重采样,resample 方法仅适用于 DatetimeIndex、TimedeltaIndex 或 PeriodIndex。因此,您可以将列转换为 timedelta,然后将其设置为索引、重新采样、reset_index 以返回到原始数据框。此外,您还需要调用 dt.total_seconds 将 minutes:seconds 转换为只有几秒钟的原始数据:

In [575]: df
Out[575]: 
             0         1
0  1977.262917  0.965209
1  1977.283350  0.969835
2  1977.303782  0.970732
3  1977.365079  0.948716
4  1977.405944  0.945410

df1 = df.copy()
df1[0] = pd.to_timedelta(df1[0], unit='s')
df1 = df1.set_index(0)

In [582]: df1
Out[582]: 
                        1
0                        
00:32:57.262917  0.965209
00:32:57.283350  0.969835
00:32:57.303782  0.970732
00:32:57.365079  0.948716
00:32:57.405944  0.945410

In [583]: df1.resample('20L')
Out[583]: 
                        1
0                        
00:32:57.262917  0.965209
00:32:57.282917  0.969835
00:32:57.302917  0.970732
00:32:57.322917       NaN
00:32:57.342917       NaN
00:32:57.362917  0.948716
00:32:57.382917       NaN
00:32:57.402917  0.945410

df2 = df1.resample('20L').reset_index()
df2[0] = df2[0].dt.total_seconds()

In [593]: df2
Out[593]: 
             0         1
0  1977.262917  0.965209
1  1977.282917  0.969835
2  1977.302917  0.970732
3  1977.322917       NaN
4  1977.342917       NaN
5  1977.362917  0.948716
6  1977.382917       NaN
7  1977.402917  0.945410

也许你可以合并然后填写 na,例如:

加载数据:

import pandas as pd
df1 = pd.read_csv('df1',sep=' ',header=None)
df2 = pd.read_csv('df2',sep=' ',header=None)
df1.columns = df2.columns = ['time','flux']

合并,排序,Forward-fill & 计算平均值:

full = pd.merge(df1,df2,on='time',how='outer').sort_values(by='time').fillna(method='ffill')
full['average'] = [(x+y)/2 for x,y in zip(full.flux_x,full.flux_y)]