如何用pandas groupby计算行业贷款损失率并为原表新增对应字段
代码错误定位
你之前测试的自定义函数代码存在三个核心问题,导致无法运行:
- 调用
apply时手动传入了整个DataFrame作为参数,而groupby.apply会自动将每个分组的子集传入自定义函数,不需要手动传参 - 函数内部引用了未定义的
loan_data变量,且分组后的子表本身就是单行业的子集,无需再对type字段做全表统计 - 没有使用
transform将聚合结果映射回原表的每一行,直接返回聚合表无法匹配原表的行维度
正确实现方案
方案1:最简实现(推荐)
使用groupby.transform直接将聚合结果对齐到原表每一行,无需额外合并,代码量最少:
# 按行业分组,计算每个行业的不良贷款率 df['lost_rate'] = df.groupby('type')['good_bad'].transform( lambda s: (s == 0).sum() / len(s) ).round(3)
代码逻辑对应:对每个行业的good_bad序列,统计等于0(不良)的记录数,除以该行业总记录数,得到的结果会自动匹配回原表同一行业的所有行。
方案2:分步骤计算后合并
如果需要留存不良数、总样本数等中间计算字段,可先聚合再关联回原表:
# 计算每个行业的不良贷款数(分子) bad_cnt = df[df['good_bad'] == 0].groupby('type').size().rename('bad_cnt') # 计算每个行业的总样本数(分母) total_cnt = df.groupby('type').size().rename('total_cnt') # 合并聚合结果并计算损失率 industry_stat = pd.concat([bad_cnt, total_cnt], axis=1).fillna(0) industry_stat['lost_rate'] = (industry_stat['bad_cnt'] / industry_stat['total_cnt']).round(3) # 将损失率关联回原表 df = df.merge(industry_stat['lost_rate'], left_on='type', right_index=True, how='left')
方案3:修正自定义函数写法
如果坚持使用自定义函数+apply的逻辑,修正后可正常运行:
# 函数入参为单个行业分组下的good_bad序列 def calc_lost_rate(series): bad_num = (series == 0).sum() total_num = len(series) return bad_num / total_num # 分组应用函数,用transform对齐回原表 df['lost_rate'] = df.groupby('type')['good_bad'].transform(calc_lost_rate).round(3)
注意事项
- 涉及“同一分组的指标要匹配回组内所有行”的需求,优先使用
transform,比手动merge的效率更高,且容易对齐 - 统计不良数时注意编码规则,本次场景下
good_bad=0为不良,因此直接判断s==0求和即可,不要将分子分母的统计逻辑搞反 - 用单独统计分子分母的方式时,如果某个行业没有不良贷款,对应的行业不会出现在不良数的统计结果中,需要补0对齐,避免关联后出现空值
内容的提问来源于stack exchange,提问作者gfchqz
相关产品推荐
相关产品推荐

