如何在 df.groupby 之后将数据框列值作为窗口大小传递?
Posted
技术标签:
【中文标题】如何在 df.groupby 之后将数据框列值作为窗口大小传递?【英文标题】:How to pass dataframe column value as window size after df.groupby? 【发布时间】:2020-04-16 13:26:45 【问题描述】: 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
这是我的示例数据框。
我想在“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
以上代码:
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
【问题讨论】:
【参考方案1】: 我们可以使用DataFrame.groupby
根据C
列的值使用groupby.rolling
。
这里我们使用df[::-1]
来反转索引的顺序,得到合适的解。
最后我们使用pd.concat
加入为C
的每个值获得的序列。
df = df.sort_values('A')
df['Rolling_sum']= pd.concat([group[::-1].groupby(df['A'])
.rolling(i,min_periods = 1)
.B.sum()
.reset_index(level = 'A',drop =True)
for i, group in df.groupby('C')])
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
【讨论】:
【参考方案2】:因为您想逐列传递动态窗口 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
如果性能很重要(取决于组的数量、组的大小、真实数据中的最佳测试),则大步前进的解决方案:
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
【讨论】:
这真的很有帮助!但是如果我在 C 中改变了值怎么办?我可以将不同的值传递给窗口大小参数吗?@ jezrael以上是关于如何在 df.groupby 之后将数据框列值作为窗口大小传递?的主要内容,如果未能解决你的问题,请参考以下文章
我如何将两个数据框列值作为键传递给2键到一个值字典,然后将结果传递到另一列?