Pandas滚动适用:传入二维数组

tv6aics1  于 2023-05-15  发布在  其他
关注(0)|答案(1)|浏览(130)

我有一个pandas dataframe,我希望在它上面执行一些滚动计算。这不是一个简单的公式,所以没有任何内置的东西。为了最小可验证完整示例的目的,让我们假设 Dataframe 是。

df = pd.DataFrame({'a': [1.1, 2.1, 3.1, 4.1, 6.1, 8.1],
                   'b': [2.2, 3.2, 4.2, 5.2, 7.2, 9.2]})

我将应用以下内容(再次简化以用于调试和说明目的)。

def func(arr):
    print(arr)
    return 0

print(arr)用来查看输入的内容。因此,要求是我希望同时对a列和b列都采用大小为4的滚动窗口。所以数组的维数应该是4 x 2。
我尽力了

df_res = df.rolling(window=4, center=False).apply(lambda x: func(x))

print(arr)给出

[ 1.1  2.1  3.1  4.1]
[ 2.1  3.1  4.1  6.1]
[ 3.1  4.1  6.1  8.1]
[ 2.2  3.2  4.2  5.2]
[ 3.2  4.2  5.2  7.2]
[ 4.2  5.2  7.2  9.2]

并且df_res给出

a    b
0  NaN  NaN
1  NaN  NaN
2  NaN  NaN
3  0.0  0.0
4  0.0  0.0
5  0.0  0.0

其仅分别为列A和B馈送4 × 1阵列。
根据这个StackOverflow答案apply a function on rolling window in Dataframe where whole dataframe is passed to function,建议使用min_periods和axis=1。

df_res = df.rolling(window=4, min_periods=2, axis=1, center=False).apply(lambda x: func(x))

但这也不是我所要求的。print(arr)给出。

[ 1.1  2.2]
[ 2.1  3.2]
[ 3.1  4.2]
[ 4.1  5.2]
[ 6.1  7.2]
[ 8.1  9.2]

并且df_res具有以下形式

a    b
0 NaN  0.0
1 NaN  0.0
2 NaN  0.0
3 NaN  0.0
4 NaN  0.0
5 NaN  0.0

所以它是在一个2 x 1的阵列中进行馈电的。我怎样才能让pandas在两列上都做一个大小为4的滚动窗口,以便输入的是一个4 x 2的数组?

hjqgdpho

hjqgdpho1#

Pandas版本1.3.0开始,您可以使用method参数:
从文档:
method:str 'single','table'},default 'single'
..版本添加::1.3.0
对每一列或行('single')或整个对象('table')执行滚动操作。
只有在方法调用中指定engine='numba'时才实现此参数。
首先,你必须安装numba

pip install numba

现在你可以这样做:

rw = df.rolling(window = 4, method = "table")
df_res = rw.apply(func, engine = "numba", raw = True)

[[1.1 2.2]]
[[1.1 2.2] 
 [2.1 3.2]]
[[1.1 2.2] 
 [2.1 3.2] 
 [3.1 4.2]]
[[1.1 2.2] 
 [2.1 3.2] 
 [3.1 4.2] 
 [4.1 5.2]]
[[2.1 3.2] 
 [3.1 4.2] 
 [4.1 5.2] 
 [6.1 7.2]]
[[3.1 4.2] 
 [4.1 5.2] 
 [6.1 7.2] 
 [8.1 9.2]]

df_res

     a    b
0  NaN  NaN
1  NaN  NaN
2  NaN  NaN
3  0.0  0.0
4  0.0  0.0
5  0.0  0.0

请注意,前三次迭代中,函数输入的大小不正确,因此您必须注意这些特定情况。遗憾的是,设置min_periods = 8无法解决这个问题,否则会出现以下错误:

ValueError: min_periods 8 must be <= window 4

你可以做的另一件事是使用numpy来获得带有sliding_window_view的滚动窗口:

from numpy.lib.stride_tricks import sliding_window_view

rw = sliding_window_view(df, (4,2))

rw

array([[[[1.1, 2.2],
         [2.1, 3.2],
         [3.1, 4.2],
         [4.1, 5.2]]],

       [[[2.1, 3.2],
         [3.1, 4.2],
         [4.1, 5.2],
         [6.1, 7.2]]],

       [[[3.1, 4.2],
         [4.1, 5.2],
         [6.1, 7.2],
         [8.1, 9.2]]]])

正如您所看到的,每个位置都是滚动窗口的一个示例。
从现在开始,您应该使用numpy来获取func返回的值。
使用pandas版本2.0.1完成。

相关问题