我们可以使用偏移量为 -3 的FixedForwardWindowIndexer 作为window,而不是事后移动,而droplevel 可以删除移动中的附加索引,但保持DataFrame 的索引对齐:
indexer = pd.api.indexers.FixedForwardWindowIndexer(window_size=4, offset=-3)
df['rolling value'] = (
df.groupby('movement')['value'].rolling(window=indexer).sum().droplevel(0)
)
df:
movement value rolling value
0 right 2 7.0
1 right 1 6.0
2 right 3 6.0
3 right 1 4.0
4 right 1 4.0
5 right 1 NaN
6 right 1 NaN
7 right 1 NaN
8 Left 5 12.0
9 Left 4 8.0
10 Left 2 5.0
11 Left 1 4.0
12 Left 1 4.0
13 Left 1 NaN
14 Left 1 NaN
15 Left 1 NaN
只是制作的系列:
indexer = pd.api.indexers.FixedForwardWindowIndexer(window_size=4, offset=-3)
print(df.groupby('movement')['value'].rolling(window=indexer).sum())
movement
Left 8 12.0
9 8.0
10 5.0
11 4.0
12 4.0
13 NaN
14 NaN
15 NaN
right 0 7.0
1 6.0
2 6.0
3 4.0
4 4.0
5 NaN
6 NaN
7 NaN
Name: value, dtype: float64
第一级 (movement) 是将值分配回 DataFrame 的问题(以及 groupby 不起作用的原因)。
droplevel(0) 制作系列:
8 12.0
9 8.0
10 5.0
11 4.0
12 4.0
13 NaN
14 NaN
15 NaN
0 7.0
1 6.0
2 6.0
3 4.0
4 4.0
5 NaN
6 NaN
7 NaN
Name: value, dtype: float64
这将与 DataFrame 正确对齐。
用于显示总和的 DataFrame 略有不同:
import pandas as pd
df = pd.DataFrame({
'movement': ['right', 'right', 'right', 'right', 'right', 'right', 'right',
'right', 'Left', 'Left', 'Left', 'Left', 'Left', 'Left',
'Left', 'Left'],
'value': [2, 1, 3, 1, 1, 1, 1, 1, 5, 4, 2, 1, 1, 1, 1, 1]
})