【发布时间】:2018-02-12 06:41:28
【问题描述】:
我在 Pandas DataFrame 中有一个时间序列。时间戳可以是不均匀的(每 1-5 分钟一个),但每 5 分钟总会有一个(分钟以 0,5,10,15,20,25,30,35,40,45,50 结尾的时间戳,55)。
例子:
2017-01-01 2:05:00 32.90
2017-01-01 2:07:30 29.83
2017-01-01 2:10:00 45.76
2017-01-01 2:15:00 16.22
2017-01-01 2:20:00 17.33
2017-01-01 2:25:00 23.40
2017-01-01 2:28:45 150.12
2017-01-01 2:30:00 100.29
2017-01-01 2:35:00 38.45
2017-01-01 2:40:00 67.12
2017-01-01 2:45:00 20.00
2017-01-01 2:50:00 58.41
2017-01-01 2:55:00 58.32
2017-01-01 3:00:00 59.89
我想获得 15 分钟块的时间加权平均值。时间戳直接在 15 分钟标记上的行(分钟以 0、15、30、45 结尾的时间戳)结束一个间隔,因此分组如下:
Group 1 (interval 2017-01-01 2:00:00):
2017-01-01 2:05:00 32.90
2017-01-01 2:07:30 29.83
2017-01-01 2:10:00 45.76
2017-01-01 2:15:00 16.22
Group 2 (interval 2017-01-01 2:15:00):
2017-01-01 2:20:00 17.33
2017-01-01 2:25:00 23.40
2017-01-01 2:28:45 150.12
2017-01-01 2:30:00 100.29
Group 3 (interval 2017-01-01 2:30:00):
2017-01-01 2:35:00 38.45
2017-01-01 2:40:00 67.12
2017-01-01 2:45:00 20.00
Group 4 (interval 2017-01-01 2:45:00):
2017-01-01 2:50:00 58.41
2017-01-01 2:55:00 58.32
2017-01-01 3:00:00 59.89
平均值必须是时间加权的,而不是一组中所有值的标准平均值。
例如,第 2 组的时间加权平均值不是 72.785,这是所有 4 个值的常规平均值。相反,它应该是:
(5 minutes / 15 minutes) * 17.33 = 5.776667 ==> The 5 minutes is taken from the difference between this timestamp and the previous timestamp
+(5 minutes / 15 minutes) * 23.40 = 7.8
+(3.75 minutes / 15 minutes) * 150.12 = 37.53
+(1.25 minutes / 15 minutes) * 100.29 = 8.3575
= **59.46417**
另外,理想情况下,15 分钟是参数化的,因为将来可能会更改为 60 分钟(每小时),但我认为这不是问题。
此外,性能在这方面非常重要。由于我的数据集大约有 10k 行,因此逐条迭代每条记录会非常慢。
我尝试研究 Pandas 的 df.rolling() 函数,但不知道如何将其直接应用于我的特定场景。
非常感谢您的帮助!
更新 1:
按照西蒙的出色解决方案,我对其进行了一些修改。
我对其进行了一些调整以适应我的具体情况:
def func(df):
if df.size == 0: return
timestep = 15*60
indexes = df.index - (df.index[-1] - pd.Timedelta(seconds=timestep))
seconds = indexes.seconds
weight = [seconds[n]/timestep if n == 0 else (seconds[n] - seconds[n - 1])/timestep
for n, k in enumerate(seconds)]
return np.sum(weight*df.values)
这是为了应对可能为空的 15 分钟间隔(数据库中缺少行)
【问题讨论】:
标签: python pandas timestamp time-series weighted-average