如何在Pandas中用groupby和cumsum生成新列?
问题描述
现有如下DataFrame:
| Class | Received | Issued |
|---|---|---|
| FD | 10 | 0 |
| FD | 0 | 2 |
| RM | 5 | 0 |
| RM | 0 | 3 |
| FD | 0 | 2 |
| PM | 5 | 0 |
| PM | 1 | 0 |
| RM | 1 | 0 |
| FD | 4 | 0 |
需要生成包含Remaining Quantity列的目标DataFrame,该列是按Class分组后,(Received - Issued)的累计求和结果:
| Class | Received | Issued | Remaining Quantity |
|---|---|---|---|
| FD | 10 | 0 | 10 |
| FD | 0 | 2 | 8 |
| RM | 5 | 0 | 5 |
| RM | 0 | 3 | 2 |
| FD | 0 | 2 | 6 |
| PM | 5 | 0 | 5 |
| PM | 1 | 0 | 6 |
| RM | 1 | 0 | 3 |
| FD | 4 | 0 | 10 |
解决方案
可以通过Pandas的分组(groupby)和累计求和(cumsum)实现,以下是两种可行写法:
写法一(分步逻辑更清晰)
import pandas as pd # 构造原始DataFrame df = pd.DataFrame({ 'Class': ['FD', 'FD', 'RM', 'RM', 'FD', 'PM', 'PM', 'RM', 'FD'], 'Received': [10, 0, 5, 0, 0, 5, 1, 1, 4], 'Issued': [0, 2, 0, 3, 2, 0, 0, 0, 0] }) # 计算每行收支差值,按Class分组后累计求和 df['Remaining Quantity'] = df.groupby('Class').apply( lambda group: (group['Received'] - group['Issued']).cumsum() ).reset_index(level=0, drop=True)
写法二(更简洁高效)
import pandas as pd # 构造原始DataFrame df = pd.DataFrame({ 'Class': ['FD', 'FD', 'RM', 'RM', 'FD', 'PM', 'PM', 'RM', 'FD'], 'Received': [10, 0, 5, 0, 0, 5, 1, 1, 4], 'Issued': [0, 2, 0, 3, 2, 0, 0, 0, 0] }) # 直接先计算全局收支差,再按Class分组做累计求和 df['Remaining Quantity'] = (df['Received'] - df['Issued']).groupby(df['Class']).cumsum()
运行任意一种写法后,都能得到目标DataFrame。第二种写法省略了额外的分组内lambda操作,执行效率更高。
内容的提问来源于stack exchange,提问作者Doyino Delima
相关产品推荐
相关产品推荐

