假设我有一个时间序列:
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
如果我使用其中一个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
但是,如果我想做一个前瞻性的总和怎么办?我尝试过这样的事情:
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
但这并不是我想要的行为。我正在寻找的输出是:
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
即 - 我想要"当前"的总和一天加上接下来的两天。我目前的解决方案还不够,因为我关心边缘发生了什么。我知道我可以通过设置两个额外的列来手动解决这个问题,这两个列分别移动了1天和2天,然后将这三列相加,但这是一个更优雅的解决方案。
答案 0 :(得分: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
答案 1 :(得分:3)
我为此苦苦挣扎,然后找到了使用shift的简单方法。
如果您想在接下来的10个周期中获得总和,请尝试:
df['NewCol'] = df['OtherCol'].shift(-10).rolling(10, min_periods = 0).sum()
我们使用shift来使“ OtherCol”比通常显示的位置高出10行,然后对前10行进行滚动总和。因为我们已经移位,所以前10行实际上是未移位列的未来10行。 :)
答案 2 :(得分:1)
也许您可以尝试bottleneck
模块。当ts
大时,bottleneck
比pandas
快得多
import bottleneck as bn
result = bn.move_sum(ts[::-1], window=3, min_count=1)[::-1]
bottleneck
还有其他滚动功能,例如move_max
,move_argmin
,move_rank
。
答案 3 :(得分:0)
Pandas最近添加了一项新功能,使您可以实施前瞻性滚动。您必须升级到熊猫1.1.0才能获得new feature。
indexer = pd.api.indexers.FixedForwardWindowIndexer(window_size=3)
ts.rolling(window=indexer, min_periods=1).sum()