Pandas - 在多列上使用 `.rolling()`

Abr*_*odj 7 python dataframe pandas rolling-computation

DataFrame考虑一只看起来像下面的熊猫

      A     B     C
0  0.63  1.12  1.73
1  2.20 -2.16 -0.13
2  0.97 -0.68  1.09
3 -0.78 -1.22  0.96
4 -0.06 -0.02  2.18
Run Code Online (Sandbox Code Playgroud)

我想使用该函数.rolling()执行以下计算t = 0,1,2

  • t选择从到 的行t+2
  • 从所有列中获取这 3 行中包含的 9 个值。调用此设置S
  • 计算 的第 75 个百分位S(或有关 的其他汇总统计数据S


例如,t = 1我们有 S = { 2.2 , -2.16, -0.13, 0.97, -0.68, 1.09, -0.78, -1.22, 0.96 } 并且第 75 个百分位数是 0.97。

我找不到让它与 一起工作的方法.rolling(),因为它显然单独使用每一列。我现在依靠 for 循环,但它真的很慢。

您对更有效的方法有什么建议吗?

ALo*_*llz 4

一种解决方案是对stack数据进行处理,然后将窗口大小乘以列数,并将结果除以列数。另外,由于您想要一个向前看的窗口,因此请颠倒堆叠的顺序DataFrame

wsize = 3
cols = len(df.columns)

df.stack(dropna=False)[::-1].rolling(window=wsize*cols).quantile(0.75)[cols-1::cols].reset_index(-1, drop=True).sort_index()
Run Code Online (Sandbox Code Playgroud)

输出:

0    1.12
1    0.97
2    0.97
3     NaN
4     NaN
dtype: float64
Run Code Online (Sandbox Code Playgroud)

对于很多列和一个小窗口的情况:

import pandas as pd
import numpy as np

wsize = 3
df2 = pd.concat([df.shift(-x) for x in range(wsize)], 1)
s_quant = df2.quantile(0.75, 1)

# Only necessary if you need to enforce sufficient data. 
s_quant[df2.isnull().any(1)] = np.NaN
Run Code Online (Sandbox Code Playgroud)

输出:s_quant

0    1.12
1    0.97
2    0.97
3     NaN
4     NaN
Name: 0.75, dtype: float64
Run Code Online (Sandbox Code Playgroud)