Pandas 将函数滚动应用到整个 window 数据帧

Pandas rolling apply function to entire window dataframe

我想将一个函数应用于滚动window。我在这里看到的所有答案都集中在应用于单个行/列,但我想将我的函数应用于整个 window。这是一个简化的例子:

import pandas as pd
data = [ [1,2], [3,4], [3,4], [6,6], [9,1], [11,2] ]
df = pd.DataFrame(columns=list('AB'), data=data)

这是df:

    A   B
0   1   2
1   3   4
2   3   4
3   6   6
4   9   1
5   11  2

取一些函数应用到整个 window:

df.rolling(3).apply(lambda x: x.shape)

在这个例子中,我想得到类似的东西:

    some_name   
0   NA  
1   NA  
2   (3,2)   
3   (3,2)   
4   (3,2)   
5   (3,2)   

当然以形状为例,说明f是将整个window作为计算对象,而不仅仅是一行/一列。我尝试为 rolling 使用 axis 关键字,为 apply 使用 raw 关键字,但没有成功。其他方法 (agg, transform) 似乎也没有提供。

当然,我可以通过列表理解来做到这一点。只是觉得有一种更简单/更清洁的方法可以做到这一点。

不适用于 pd.DataFrame.rolling .... 该函数迭代地应用于列,接收一系列 floats/NaN,并返回一系列 floats/NaN,逐个-一。我想你的直觉会更好....

def rolling_pipe(dataframe, window, fctn):
    return pd.Series([dataframe.iloc[i-window: i].pipe(fctn) 
                      if i >= window else None 
                      for i in range(1, len(dataframe)+1)],
                     index = dataframe.index) 

df.pipe(rolling_pipe, 3, lambda x: x.shape)

提供给您的应用函数的参数是一个系列,其索引 属性 包含开始、停止和步骤属性。

RangeIndex(start=0, stop=2, step=1)

您可以使用它来查询您的数据框。

df = pd.DataFrame([('Sean', i) for i in range(1,11)], columns=['name', 'value'])

def func(series):
    view = df.iloc[series.index]
    # use view to do something...
    count = len(view[view.value.isin([1,2,8])])
    return count

df['count'] = df.value.rolling(2).apply(func)

可能有更有效的方法来执行此操作,但我不确定该怎么做。