【问题标题】:Pandas - Using `.rolling()` on multiple columnsPandas - 在多列上使用`.rolling()`
【发布时间】:2019-01-07 23:53:58
【问题描述】:

考虑一个熊猫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 循环,但它真的很慢。

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

【问题讨论】:

  • this 怎么样
  • 你有足够的代表知道不要将数据发布为图片
  • @RushabhMehta:这正是我想要使用的函数,但我不明白如何将 A、B 和 C 3 列中的数据拉到一起来计算百分位数。
  • 只需将其粘贴为文本并将其格式化为代码即可。阅读:stackoverflow.com/questions/20109391/…
  • 我不喜欢涉及重塑事物的答案。我使用scipy.ndimage.generic_filter 来正确执行此操作,尽管它需要一些试验和错误才能获得与 Pandas 的 rolling 的 center=False 效果相同的效果。

标签: python pandas dataframe rolling-computation


【解决方案1】:

一种解决方案是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 个条目而不是每 3 个条目。在我的真实数据集中,我的列数比 3 多得多,所以这实际上在计算上产生了巨大的差异。
  • @Abramodj 我发现 1000 倍的列数需要 8 倍的时间。因此,只要您有合理数量的列,多余的列可能不会杀死您。目前尚不清楚您是否需要一个非常高效的解决方案,而不是仅仅解决您的问题。让我看看我能做什么。
  • 其实我有一万多列
  • 一千左右,所以这种情况下for循环其实是可行的。我只是想了解这是否可以做到,因为它在其他情况下可能非常有用。
  • @ALollz 我认为你应该在堆栈中指定 dropna=True ,否则窗口大小会保持一致
【解决方案2】:

你可以使用 numpy ravel。你仍然可能不得不使用 for 循环。

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

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

【讨论】:

  • 这是我目前正在使用的解决方案,它需要一个 for 循环。它没有rolling那么快,因为它没有矢量化
  • @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)。
猜你喜欢
  • 2020-09-25
  • 2018-08-04
  • 2018-01-10
  • 2019-06-23
  • 2021-05-18
  • 2021-09-26
  • 1970-01-01
  • 2020-06-16
  • 2019-04-29
相关资源
最近更新 更多