我有一个带有datetime列(我用作DatetimeIndex)的Pandas数据帧,该列具有一个分类列和一个数值列。我想在类别列与当前行相同的情况下,在滞后于当前行(不包括在内)的短(十天)窗口中,对数字列应用复杂的函数。
作为人为的示例:
name = ['steve', 'bob', 'harry', 'jeff'] * 5
df = pd.DataFrame(
index=pd.DatetimeIndex(start='2018-10-10', end='2018-10-29', freq='D'),
data={'value': [x for x in range(20)],
'name': names
}
)
生成一个简单的数据框,我想在其中添加另一列(result
),该列用于计算行数*'value'中值的总和(或其他内容-只是一个公式不是Pandas的内置函数)。因此,对于上面的数据框,我想要以下内容:
num name result
2018-10-10 0 steve NaN
2018-10-11 1 bob NaN
2018-10-12 2 harry NaN
2018-10-13 3 jeff NaN
2018-10-14 4 steve 0
2018-10-15 5 bob 1
2018-10-16 6 harry 2
2018-10-17 7 jeff 3
2018-10-18 8 steve 8
2018-10-19 9 bob 12
2018-10-20 10 harry 16
2018-10-21 11 jeff 20
2018-10-22 12 steve 24
2018-10-23 13 bob 28
2018-10-24 14 harry 32
2018-10-25 15 jeff 36
2018-10-26 16 steve 40
2018-10-27 17 bob 44
2018-10-28 18 harry 48
2018-10-29 19 jeff 52
我可以为此编写自己的函数,并在pandas.apply
中使用它:
def rolling_apply(df, time, window_size=timedelta(days=10)):
event_time = time
event_name = df[df.index == time]['names'].iloc[0]
return df[
(df['names'] == event_name) &
(df.index < event_time) &
(df.index >= event_time - window_size)
]
df['result'] = df.apply(lambda x: rolling_apply(df, x.name)['value'].sum() * rolling_apply(df, x.name).count(), axis=1)
但是随着数据的增长,性能很快变得非常糟糕。 pandas.rolling.apply
似乎很合适,但我不能完全满足我的需求。
任何建议或帮助将不胜感激!