如何在前瞻性的基础上使用Pandas rolling_*函数

use*_*645 12 python pandas

假设我有一个时间序列:

In[138] rng = pd.date_range('1/10/2011', periods=10, freq='D')
In[139] ts = pd.Series(randn(len(rng)), index=rng)
In[140]
Out[140]:
2011-01-10    0
2011-01-11    1
2011-01-12    2
2011-01-13    3
2011-01-14    4
2011-01-15    5
2011-01-16    6
2011-01-17    7
2011-01-18    8
2011-01-19    9
Freq: D, dtype: int64
Run Code Online (Sandbox Code Playgroud)

如果我使用其中一个rolling_*函数,例如rolling_sum,我可以获得我想要的向后看滚动计算的行为:

In [157]: pd.rolling_sum(ts, window=3, min_periods=0)
Out[157]: 
2011-01-10     0
2011-01-11     1
2011-01-12     3
2011-01-13     6
2011-01-14     9
2011-01-15    12
2011-01-16    15
2011-01-17    18
2011-01-18    21
2011-01-19    24
Freq: D, dtype: float64
Run Code Online (Sandbox Code Playgroud)

但是,如果我想做一个前瞻性的总和怎么办?我尝试过这样的事情:

In [161]: pd.rolling_sum(ts.shift(-2, freq='D'), window=3, min_periods=0)
Out[161]: 
2011-01-08     0
2011-01-09     1
2011-01-10     3
2011-01-11     6
2011-01-12     9
2011-01-13    12
2011-01-14    15
2011-01-15    18
2011-01-16    21
2011-01-17    24
Freq: D, dtype: float64
Run Code Online (Sandbox Code Playgroud)

但这并不是我想要的行为.我正在寻找的输出是:

2011-01-10    3
2011-01-11    6
2011-01-12    9
2011-01-13    12
2011-01-14    15
2011-01-15    18
2011-01-16    21
2011-01-17    24
2011-01-18    17
2011-01-19    9
Run Code Online (Sandbox Code Playgroud)

即 - 我想要"当前"日加上接下来两天的总和.我目前的解决方案还不够,因为我关心边缘发生了什么.我知道我可以手动解决这个问题,方法是设置两个额外的列,分别移动1天和2天,然后将这三列相加,但必须有一个更优雅的解决方案.

And*_*den 19

为什么不在反转系列上做(并反过来回答):

In [11]: pd.rolling_sum(ts[::-1], window=3, min_periods=0)[::-1]
Out[11]:
2011-01-10     3
2011-01-11     6
2011-01-12     9
2011-01-13    12
2011-01-14    15
2011-01-15    18
2011-01-16    21
2011-01-17    24
2011-01-18    17
2011-01-19     9
Freq: D, dtype: float64
Run Code Online (Sandbox Code Playgroud)

  • 聪明的回答,谢谢。尽管这仅在您将所有日期都在一个范围内时才有效。在您的情况下,您没有指定频率。例如,当您指定 freq='D' 时,此解决方案不再有效。因此,如果我缺少数据或可变采样频率,这将不起作用。似乎这将是正确实施的一个非常有价值的功能。有谁知道它是否在管道中? (2认同)

ort*_*ort 13

Pandas 最近添加了一项新功能,使您能够实现前瞻滚动。您必须升级到 pandas 1.1.0 才能获得新功能

indexer = pd.api.indexers.FixedForwardWindowIndexer(window_size=3)
ts.rolling(window=indexer, min_periods=1).sum()
Run Code Online (Sandbox Code Playgroud)


小智 5

我为此苦苦挣扎,然后找到了一种使用 shift 的简单方法。

如果您想要接下来 10 个期间的滚动总和,请尝试:

df['NewCol'] = df['OtherCol'].shift(-10).rolling(10, min_periods = 0).sum()
Run Code Online (Sandbox Code Playgroud)

我们使用 shift 以便“OtherCol”在正常位置之前显示 10 行,然后我们对前 10 行进行滚动求和。因为我们移位了,前 10 行实际上是未移位列的未来 10 行。:)

  • 似乎是一个不错的方法,但我相信您会丢失最初的 10 行,不是吗? (2认同)