Python Pandas:按分组及日期条件创建聚合求和新列
分组后按日期前置求和的实现方案
核心思路
要实现「按Column A分组,对当前行Column C日期之前的所有Column B值求和」,不能直接用全局分组求和,需要结合分组内日期排序、**累计求和(cumsum)和偏移(shift)**三个步骤:
- 确保日期列是datetime类型,避免排序出错
- 分组内按日期排序,保证时间顺序正确
- 计算分组内Column B的累计和,再偏移一位得到当前行之前的总和
- 空值填充为0(第一行没有前置数据)
代码实现
方法一:分组内lambda处理
import pandas as pd # 示例数据 data = { 'Column A': ['Bill', 'John', 'Bill', 'Bill'], 'Column B': [1, 0, 1, 0], 'Column C': ['2022-09-01', '2022-09-02', '2022-09-04', '2022-09-10'] } df = pd.DataFrame(data) # 转换日期列类型 df['Column C'] = pd.to_datetime(df['Column C']) # 生成NEW COL列 df['NEW COL'] = df.groupby('Column A').apply( lambda group: group.sort_values('Column C')['Column B'].cumsum().shift(1) ).reset_index(level=0, drop=True).fillna(0).astype(int) print(df)
方法二:先全局排序再分组计算(更高效)
如果数据量较大,推荐这种方式,避免lambda的额外开销:
import pandas as pd # 示例数据 data = { 'Column A': ['Bill', 'John', 'Bill', 'Bill'], 'Column B': [1, 0, 1, 0], 'Column C': ['2022-09-01', '2022-09-02', '2022-09-04', '2022-09-10'] } df = pd.DataFrame(data) # 转换日期列类型并按分组+日期排序 df['Column C'] = pd.to_datetime(df['Column C']) df = df.sort_values(['Column A', 'Column C']) # 计算分组累计和并偏移 df['NEW COL'] = df.groupby('Column A')['Column B'].cumsum().shift(1).fillna(0).astype(int) # 还原原始索引顺序(可选) df = df.sort_index() print(df)
输出结果
| Column A | Column B | Column C | NEW COL | |
|---|---|---|---|---|
| 0 | Bill | 1 | 2022-09-01 | 0 |
| 1 | John | 0 | 2022-09-02 | 0 |
| 2 | Bill | 1 | 2022-09-04 | 1 |
| 3 | Bill | 0 | 2022-09-10 | 2 |
原代码问题说明
你之前写的df.groupby('Column A')['Column B'].transform(np.sum)是计算每个分组的全局总和,无法区分当前行日期的先后关系,所以必须结合排序和累计求和才能实现前置数据的求和逻辑。
内容的提问来源于stack exchange,提问作者Nicholas Johnson
相关产品推荐
相关产品推荐

