Python pandas时间序列插值和正则化

21

我第一次使用Python Pandas。我有5分钟滞后的csv格式交通数据:

...
2015-01-04 08:29:05,271238
2015-01-04 08:34:05,329285
2015-01-04 08:39:05,-1
2015-01-04 08:44:05,260260
2015-01-04 08:49:05,263711
...

存在几个问题:

  • 某些时间戳存在缺失数据(-1)
  • 存在缺失条目(也有两三个连续小时的情况)
  • 观测频率不完全是5分钟,实际上偶尔会丢失几秒钟

我希望获得一个规则的时间序列,每5分钟一个条目(确切地说没有缺失值)。我已经成功地使用以下代码对时间序列进行了插值以近似-1值:

ts = pd.TimeSeries(values, index=timestamps)
ts.interpolate(method='cubic', downcast='infer')

我应该如何同时插值和正则化观测频率?感谢大家的帮助。

1个回答

29

-1更改为NaN:

ts[ts==-1] = np.nan

然后将数据重新采样为5分钟频率。

ts = ts.resample('5T')

请注意,默认情况下,如果两个测量值在同一5分钟内,则resample将这些值平均计算。

最后,您可以根据时间对时间序列进行线性插值:

ts = ts.interpolate(method='time')

看起来你的数据已经大致上是每五分钟一次的频率,你可能需要以更短的频率重新采样,这样三次样条插值或自然样条插值就可以平滑曲线:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

values = [271238, 329285, -1, 260260, 263711]
timestamps = pd.to_datetime(['2015-01-04 08:29:05',
                             '2015-01-04 08:34:05',
                             '2015-01-04 08:39:05',
                             '2015-01-04 08:44:05',
                             '2015-01-04 08:49:05'])

ts = pd.Series(values, index=timestamps)
ts[ts==-1] = np.nan
ts = ts.resample('T').mean()

ts.interpolate(method='spline', order=3).plot()
ts.interpolate(method='time').plot()
lines, labels = plt.gca().get_legend_handles_labels()
labels = ['spline', 'time']
plt.legend(lines, labels, loc='best')
plt.show()

enter image description here


谢谢,它完美地运行了!有一种方法可以先将常规的5分钟时间戳添加到系列中,并使用nan作为值进行插值,然后再使用三阶样条插值? - riccamini
1
重采样是在插值之前和独立于插值进行的。您不必进行线性插值。只需删除 ts.interpolate(method='time').plot() 这一行以及与 labels 中的 time 相关联的内容即可。然后上述代码将仅使用三阶样条插值对数据进行插值。 - unutbu
1
how='mean' 告诉 resample 如果多行数据落在同一时间段内(在本例中,T 表示每个时间段的频率为 1 分钟),如何聚合这些值。 - unutbu
2
@DaveX:当然可以。不要使用resample对Series进行重采样,而是使用reindex添加带有NaN值的新行。然后调用Series.interpolate(method='time')将使用插值方法填充缺失值。 - unutbu
2
或者你可以像HYRY在这里展示的那样使用combine_first。(想一想,combine_first可能是更好的解决方案,因为如果你使用reindex,你将不得不将旧索引与新索引合并...) - unutbu
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接