满足条件的前一行的熊猫平均值

时间:2021-02-11 15:50:57

标签: python pandas performance dataframe numpy

我有一个巨大的数据框(> 20m 行),每行包含一个时间戳和一个数字变量 X。我想分配一个新列,其中对于每一行,这个新列中的值是 X 的平均值指定时间窗口内的前一行,例如时间戳不超过 5 分钟前的所有行的平均值。由于时间戳不是固定间隔的,我不能只取固定切片

目前我发现的最佳方法是“毛毛虫”算法,它循环遍历数据帧一次,并根据时间帧窗口是否被破坏来移动开始/结束索引。然而,事实证明这非常缓慢,我想知道是否有一种巧妙的矢量化方法来做到这一点?也许涉及 np 数组?

谢谢

1 个答案:

答案 0 :(得分:1)

将时间戳设置为索引并使用滚动()function。您可以将窗口设置为时间偏移。例如:

# creating the dataset
import numpy as np

np.random.seed(113)

df = pd.DataFrame({'timestamp': pd.date_range('2021-01-01', '2021-01-02', freq='1S'),
                 'value': np.random.randint(1,10,86401)})

# This randomly drops rows to make the dataset fragmented
df = df.drop(np.random.choice(range(1,86401), 85000, replace=False))
df.head(10)
              timestamp  value
0   2021-01-01 00:00:00      6
58  2021-01-01 00:00:58      7
237 2021-01-01 00:03:57      9
390 2021-01-01 00:06:30      7
481 2021-01-01 00:08:01      8
575 2021-01-01 00:09:35      4
580 2021-01-01 00:09:40      9
735 2021-01-01 00:12:15      7
894 2021-01-01 00:14:54      2
927 2021-01-01 00:15:27      5

现在使用滚动 () 函数,窗口为 5 分钟。

df['rolling_mean'] = df.set_index('timestamp') \
  .rolling('5T', closed='left')['value'].mean().values

df.head(10)
              timestamp  value  rolling_mean
0   2021-01-01 00:00:00      6           NaN
58  2021-01-01 00:00:58      7      6.000000
237 2021-01-01 00:03:57      9      6.500000
390 2021-01-01 00:06:30      7      9.000000
481 2021-01-01 00:08:01      8      8.000000
575 2021-01-01 00:09:35      4      7.500000
580 2021-01-01 00:09:40      9      6.333333
735 2021-01-01 00:12:15      7      7.000000
894 2021-01-01 00:14:54      2      7.000000
927 2021-01-01 00:15:27      5      4.500000

这应该是前 5 分钟内的意思,不包括当前时间。