如何在Pandas中基于color和Mon列实现分组累积滚动求和?
解决Pandas分组后滚动求和的问题
问题分析
你之前用df.groupby(by=['color','Mon']).rolling(window=2).sum()或apply的方式得到的结果结构不符合预期,原因是直接调用rolling会返回带有分组键+原索引的多级索引结果,无法直接和原DataFrame的结构对齐。想要保持原DataFrame的结构并得到对应行的滚动求和结果,应该使用transform方法。
解决方案
1. 滚动窗口求和(窗口大小2)
如果需要每个(color, Mon)分组内,对number列做窗口为2的滚动求和(即当前行和前一行的和),同时保持原DataFrame的结构,可以用groupby配合transform:
import pandas as pd # 初始化你的DataFrame df = pd.DataFrame([1, 2, 1, 2, 3, 4, 1, 2, 1, 2, 3, 4, 1, 1, 2], index=pd.MultiIndex.from_arrays( [[30,20,15,10,20,20,5,15,20,10,10,30,20,15,10], ['red','red','red','red','red','red','blue','blue','blue','blue','blue','blue','Green','Green','Green'], ['Feb','Feb','Mar','Mar','Mar','Mar','Feb','Feb','Mar','Mar','Mar','Mar','Feb','Mar','Mar']], names=['number','color','Mon'])).reset_index() # 计算分组内滚动窗口为2的求和,min_periods=1确保第一个元素保留自身值 df['rolling_sum'] = df.groupby(['color', 'Mon'])['number'].transform( lambda x: x.rolling(window=2, min_periods=1).sum() )
2. 累积求和(从第一个元素到当前元素累加)
如果你的“累积滚动求和”指的是分组内从首行到当前行的累加(而非固定窗口大小),则直接用cumsum即可:
df['cumulative_sum'] = df.groupby(['color', 'Mon'])['number'].cumsum()
结果说明
- 使用
transform会自动将分组内的计算结果映射回原DataFrame的对应行,完美匹配原数据结构。 min_periods=1参数可根据需求调整:如果不需要第一个元素的结果(希望显示NaN),可以去掉该参数,默认min_periods=window(即2)。
内容的提问来源于stack exchange,提问作者rra
相关产品推荐
相关产品推荐

