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

时间:2015-12-31 06:38:15

标签: python numpy pandas scipy time-series

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

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。通过这种方式,我可以直接平均两个数据集,因为现在它们大致对齐。那么如何使用pandas或numpy,scipy等在python中实现这一点。或者是否有更好的方法(除了我想的方式)来实现这项工作?也许插值?谢谢你们。

2 个答案:

答案 0 :(得分:3)

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将分钟数:秒转换为仅原始数据的秒数:

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

答案 1 :(得分:1)

也许你可以合并,然后填写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']

合并,排序,前向填充&am​​p;计算平均值:

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)]

output