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

时间:2018-07-31 14:31:12

标签: python pandas dataframe 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

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

  • tt+2的行中选择
  • 从所有列中获取这3行中包含的9个值。将此集合称为S
  • 计算S的第75个百分位数(或其他有关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循环,但这确实很慢。

您对采用更有效的方法有何建议?

2 个答案:

答案 0 :(得分:3)

一种解决方案是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()

输出:

0    1.12
1    0.97
2    0.97
3     NaN
4     NaN
dtype: float64

在多列和小窗口的情况下:

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

输出:s_quant

0    1.12
1    0.97
2    0.97
3     NaN
4     NaN
Name: 0.75, dtype: float64

答案 1 :(得分:0)

您可以使用numpy ravel。仍然可能需要使用循环。

for i in range(0,3):
    print(df.iloc[i:i+3].values.ravel())

如果您的t步长为3s,则可以使用numpy reshape函数创建一个n*9数据框。