Pandas如何基于布尔列按分组实现分账户条件累计求和
pandas分组条件累计计算方案
通过「构造有效发生额+分组累计求和」的方式即可实现需求,全程使用pandas原生向量化运算,无需手写逐行循环,性能优异。
1. 原始数据集构造
对应测试数据构造代码:
import pandas as pd import numpy as np d = { 'name': ['Adam', 'Adam', 'Adam', 'Benj', 'Benj', 'Adam'], 'is_valid': [True, False, True, True, False, True], 'account': ['debit', 'credit', 'credit', 'credit', 'debit', 'credit'], 'transaction': [10, 10, 10, 10, 10, 10] } df = pd.DataFrame(data=d)
2. 计算逻辑实现
2.1 生成待累计的有效发生额
按照规则,只有同时满足当前行is_valid为True、账户类型匹配两个条件时,当前行的transaction值才需要计入累计,否则记为0(不改变累计结果)。大数据量场景下推荐用numpy.where实现,性能远高于逐行apply:
# 生成credit类有效发生额 df['_credit_tmp'] = np.where( (df['is_valid'] == True) & (df['account'] == 'credit'), df['transaction'], 0 ) # 生成debit类有效发生额 df['_debit_tmp'] = np.where( (df['is_valid'] == True) & (df['account'] == 'debit'), df['transaction'], 0 )
2.2 按姓名分组逐行累计
按name列分组后对临时列做逐行累计求和,得到最终的累计列,之后删除中间临时列即可:
df['credit_cumulative'] = df.groupby('name')['_credit_tmp'].cumsum() df['debit_cumulative'] = df.groupby('name')['_debit_tmp'].cumsum() # 清理临时列 df = df.drop(columns=['_credit_tmp', '_debit_tmp'])
3. 结果验证
运行代码后得到的DataFrame完全匹配预期输出:
| name | is_valid | account | transaction | credit_cumulative | debit_cumulative |
|---|---|---|---|---|---|
| Adam | True | debit | 10 | 0 | 10 |
| Adam | False | credit | 10 | 0 | 10 |
| Adam | True | credit | 10 | 10 | 10 |
| Benj | True | credit | 10 | 10 | 0 |
| Benj | False | debit | 10 | 10 | 0 |
| Adam | True | credit | 10 | 20 | 10 |
内容的提问来源于stack exchange,提问作者jds
相关产品推荐
相关产品推荐

