Python Pandas-在多个列上使用“.rolling()”

Python Pandas-在多个列上使用“.rolling()”,python,pandas,dataframe,rolling-computation,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执行以下计算: 从t到t+2 从所有列中获取这3行中包含的9个值。调用此集合S 计算S的第75个百分位(或关于S的其他汇总统计) 例如,对于t=1,我们有 S=

考虑一个类似于下面的熊猫
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
执行以下计算:

  • t
    t+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循环,但它真的很慢


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

一种解决方案是将数据堆叠起来,然后将窗口大小乘以列数,并将结果切片为列数。此外,由于您需要一个前瞻性窗口,请颠倒堆叠的
数据帧的顺序

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\u数量

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

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

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

如果您的
t
步骤为3s,您可以使用numpy
重塑
函数创建
n*9
数据帧。

如果您有足够的代表知道不将数据发布为picture@RushabhMehta:这正是我试图使用的函数,但我不明白如何从3列A中提取数据,B和C一起计算百分位数。只需将其粘贴为文本并将其格式化为代码。读这个:我不喜欢涉及重塑事物的答案。我曾经正确地做到这一点,尽管它需要一些尝试和错误来获得与Pandas的
rolling
center=False
效果相同的效果。这是我目前使用的解决方案,需要一个for循环。它没有滚动的速度快,因为它没有滚动的速度快vectorized@Abramodj你试过这个:
x=pd.concat([df,df.shift(-1),df.shift(-2)],axis=1)
然后
x['m']=x.mean(axis=1)
。对于四分位数,您可以使用
x['q3']=x.quantile(0.75,axis=1)
。这是不等价的,因为它会计算更多次统计信息。这是因为窗口将每1个条目移动一次,而不是每3个条目移动一次。在我的真实数据集中,我有比3更多的列,所以从计算角度来说,这实际上是一个巨大的差异。@Abramodj我发现1000倍的列数需要8倍的时间。因此,只要你有一个合理的列数,多余的可能不会杀死你。不清楚你是否需要一个非常高效的解决方案,而不仅仅是一个问题的解决方案。让我看看我能做些什么。事实上,我有1000个以上的10k列,所以for循环在这种情况下实际上是可行的。我只是想知道这是否可以做到,因为它在其他情况下可能非常有用。@ALollz我认为您应该在堆栈中指定dropna=True,否则窗口大小将是一致的