本文介绍如何在 pandas 中对多列(如 date_m 和 corporate)进行分组后,高效计算某分类变量(如 vehicle type)中指定值(如 'truck')在每组内的百分比,并将其作为新列添加到聚合结果中。
本文介绍如何在 pandas 中对多列(如 date_m 和 corporate)进行分组后,高效计算某分类变量(如 vehicle type)中指定值(如 'truck')在每组内的百分比,并将其作为新列添加到聚合结果中。
在数据分析中,常需在多维分组(如按月份和企业属性组合)后,进一步统计某分类字段(如车辆类型)的构成比例。例如,为评估不同月份、不同客户类型(Corporate=0/1)下的车型分布,需计算每组中 truck 占比。该需求无法通过简单的 .agg() 直接实现,因为涉及组内条件计数与组长度的比值运算,需借助 .apply() 配合自定义逻辑。
核心方法是:在已创建的 GroupBy 对象(如 df_group = df_no_insurance.groupby(['Date_M', 'Corporate']))上,使用 .apply() 对每个子组执行匿名函数,统计 'Vehicle type' == 'truck' 的行数,再除以该组总行数并乘以 100 得到百分比:
results['Percentage of Trucks'] = df_group.apply(
lambda x: (x['Vehicle type'] == 'truck').sum() / len(x) * 100
)✅ 关键说明:
- x 是每个分组对应的子 DataFrame;
- (x['Vehicle type'] == 'truck').sum() 利用布尔索引自动转为整数求和(True=1, False=0),等价于 x[x['Vehicle type']=='truck'].shape[0],但更简洁高效;
- len(x) 等价于 x.shape[0],安全获取组内行数;
- 结果自动对齐至 MultiIndex,无需手动重置索引。
⚠️ 注意事项:
- 若某组为空(极少见),len(x) 为 0,会导致除零警告。生产环境建议增加防御逻辑:
results['Percentage of Trucks'] = df_group.apply( lambda x: ((x['Vehicle type'] == 'truck').sum() / len(x) * 100) if len(x) > 0 else 0 ) - 若需保留小数位数,可链式调用 .round(2):
results['Percentage of Trucks'] = df_group.apply(...).round(2)
- 此方法适用于任意分类列和任意目标值(如 'automobile' 或多个值的并集),只需修改布尔条件即可。
综上,.apply() 是处理“组内比例类聚合”的标准范式——它灵活、可读性强,且能无缝集成到已有分组流程中,是 Pandas 高级分组分析不可或缺的工具。








