Asm*_*ani 7 python group-by sum pandas rolling-computation
A B C
0 1 10 2
1 1 15 2
2 1 14 2
3 2 11 4
4 2 12 4
5 2 13 4
6 2 16 4
7 1 18 2
Run Code Online (Sandbox Code Playgroud)
这是我的示例 DataFrame。
我想在“A”列上应用 groupby,
根据列 'C' 的值在列 'B' 上应用滚动总和,这意味着当 A 为 1 时,窗口大小应为 2 而不是 NaN 我想要剩余值的总和,而不管窗口大小如何。
目前我的输出是:
A
1 0 25.0
1 29.0
2 32.0
7 NaN
2 3 23.0
4 25.0
5 29.0
6 NaN
Run Code Online (Sandbox Code Playgroud)
上面的代码:
df['B'].groupby(df['A']).rolling(df['C'][0]).sum().shift(-1)
当 C = 4 时,我希望滚动窗口为 4 并且不想要 NaN
所需的输出应如下所示:
A B C Rolling_sum
0 1 10 2 25
1 1 15 2 29
2 1 14 2 32
7 1 18 2 18
3 2 11 4 52
4 2 12 4 41
5 2 13 4 29
6 2 16 4 16
Run Code Online (Sandbox Code Playgroud)
因为您想按列传递动态窗口,所以C使用 lambda 函数并更改顺序iloc[::-1]:
df = df.sort_values('A')
df['Rolling_sum'] = (df.iloc[::-1].groupby('A')
.apply(lambda x: x.B.rolling(x.C.iat[0], min_periods=0).sum())
.reset_index(level=0, drop=True))
print (df)
A B C Rolling_sum
0 1 10 2 25.0
1 1 15 2 29.0
2 1 14 2 32.0
7 1 18 2 18.0
3 2 11 4 52.0
4 2 12 4 41.0
5 2 13 4 29.0
6 2 16 4 16.0
Run Code Online (Sandbox Code Playgroud)
如果性能很重要,则采用跨步解决方案(取决于组数、组大小、实际数据中的最佳测试):
def rolling_window(a, window):
a = np.concatenate([[0] * (window - 1), a])
shape = a.shape[:-1] + (a.shape[-1] - window + 1, window)
strides = a.strides + (a.strides[-1],)
return np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides).sum(axis=1)
df = df.sort_values('A')
df['Rolling_sum'] = (df.iloc[::-1].groupby('A')
.apply(lambda x: pd.Series(rolling_window(x.B, x.C.iat[0]),
index=x.index))
.reset_index(level=0, drop=True))
print (df)
A B C Rolling_sum
0 1 10 2 25
1 1 15 2 29
2 1 14 2 32
7 1 18 2 18
3 2 11 4 52
4 2 12 4 41
5 2 13 4 29
6 2 16 4 16
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
293 次 |
| 最近记录: |