【问题标题】:Average time series with missing time value缺少时间值的平均时间序列
【发布时间】:2016-04-05 04:18:49
【问题描述】:

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

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

【问题讨论】:

  • 我会选择插值。为此有一个特殊的 scipy 类。

标签: python numpy pandas scipy time-series


【解决方案1】:

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

【讨论】:

  • 感谢您的回答,这是我想要的。
  • 但是你知道如何从我的原始数据集中获取包含 nans 的数据集吗?
【解决方案2】:

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

合并、排序、前向填充和计算平均值:

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

【讨论】:

  • 我也有同样的想法。但我认为如果我这样做,最好做滚动平均值或中位数?
  • 帮不了你,这取决于你的目标。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-25
  • 2012-08-02
  • 1970-01-01
  • 2015-04-30
  • 2012-08-17
  • 2018-06-08
  • 1970-01-01
相关资源
最近更新 更多