如何在Python Pandas中为分组聚合函数应用多筛选条件?
按Fruit分组计算多条件Number求和的高效实现
问题说明
现有这份DataFrame:
import pandas as pd data = {'Fruit':['apple', 'apple', 'apple', 'kivi', 'kivi', 'kivi'], 'Y_or_N': ['Y', 'N', 'Y', 'N', 'N', 'Y'], 'A_or_B': ['A', 'A', 'B', 'A', 'B', 'A'], 'Number': [3, 5, 6, 7, 2, 4]} df = pd.DataFrame.from_dict(data)
需要按Fruit分组,对Number列计算三类求和值:
- 分组内所有值的总和(sum_all)
- 分组内
Y_or_N为'Y'时的总和(sum_Y) - 分组内
A_or_B为'A'时的总和(sum_A)
之前的代码仅能实现单一条件求和,现在需要一次性完成计算,无需拆分多个DataFrame再合并,最终要得到如下结果:
| Fruit | sum_all | sum_Y | sum_A |
|---|---|---|---|
| apple | 14 | 9 | 8 |
| kivi | 13 | 4 | 11 |
高效实现方式
直接借助groupby.agg()或自定义聚合函数,一次分组即可算出所有结果:
方式1:用字典直接定义聚合规则
在agg()中直接指定每个求和项的计算逻辑,一步到位:
new_df = df.groupby('Fruit').agg( sum_all=('Number', 'sum'), sum_Y=('Number', lambda x: x[df.loc[x.index, 'Y_or_N'] == 'Y'].sum()), sum_A=('Number', lambda x: x[df.loc[x.index, 'A_or_B'] == 'A'].sum()) ).reset_index()
方式2:自定义聚合函数(逻辑更直观)
编写一个聚合函数封装三个求和逻辑,分组后直接调用:
def calc_group_sums(group): return pd.Series({ 'sum_all': group['Number'].sum(), 'sum_Y': group[group['Y_or_N'] == 'Y']['Number'].sum(), 'sum_A': group[group['A_or_B'] == 'A']['Number'].sum() }) new_df = df.groupby('Fruit').apply(calc_group_sums).reset_index()
方式3:布尔掩码转数值求和(大数据集更高效)
将条件转换为0/1布尔值,与Number相乘后求和,这种方法在处理大规模数据时性能更优:
new_df = df.assign( is_Y=df['Y_or_N'] == 'Y', is_A=df['A_or_B'] == 'A' ).groupby('Fruit').agg( sum_all=('Number', 'sum'), sum_Y=('Number', lambda x: (x * df.loc[x.index, 'is_Y']).sum()), sum_A=('Number', lambda x: (x * df.loc[x.index, 'is_A']).sum()) ).reset_index()
三种方式均可直接输出目标结果,其中方式2逻辑最易懂,方式3适合处理大数据量场景。
内容的提问来源于stack exchange,提问作者Katrina
相关产品推荐
相关产品推荐

