熊猫滚动适用于df,其中基于当前行的值进行过滤

时间:2018-12-27 03:49:21

标签: python pandas dataframe

我有一个带有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似乎很合适,但我不能完全满足我的需求。

任何建议或帮助将不胜感激!

0 个答案:

没有答案