Pandas/Numpy加权平均ZeroDivisionError:lambda分组聚合报错求助
解决加权平均聚合时的ZeroDivisionError问题
我之前也碰到过一模一样的情况——当分组内的权重总和为0时,np.average确实会直接抛出除零错误。这里有几个简单又健壮的解决思路:
方法一:提前检查权重总和(推荐)
把原来的lambda函数替换成一个更清晰的命名函数,在计算加权平均前先判断权重总和是否为0,再返回合理的默认值(比如np.nan,方便后续缺失值处理):
import numpy as np import pandas as pd def safe_weighted_mean(x, weights_series): # 提取当前分组对应的权重 group_weights = weights_series.loc[x.index] total_weight = group_weights.sum() if total_weight == 0: # 根据业务需求选择返回值:NaN/0/其他 return np.nan return np.average(x, weights=group_weights) # 定义聚合字典,传入权重列 agg_dict = { 'DRESS_AMT': 'max', 'FACE_AMT': 'sum', 'Other_AMT': {'weighted_mean': lambda x: safe_weighted_mean(x, df['WEIGHTS'])} } # 执行分组聚合 df2 = df.groupby(['ID','COL1'], as_index=False).agg(agg_dict)
如果还是偏好lambda的简洁性,也可以写成紧凑版(可读性稍差,但功能一致):
wm = lambda x: np.average(x, weights=df.loc[x.index, 'WEIGHTS']) if df.loc[x.index, 'WEIGHTS'].sum() != 0 else np.nan agg_dict = {'DRESS_AMT': 'max', 'FACE_AMT': 'sum', 'Other_AMT': {'weighted_mean' : wm}} df2 = df.groupby(['ID','COL1'], as_index=False).agg(agg_dict)
方法二:捕获异常处理
如果想更灵活地处理错误(比如记录日志),可以用try-except捕获ZeroDivisionError:
wm = lambda x: ( np.average(x, weights=df.loc[x.index, 'WEIGHTS']) if df.loc[x.index, 'WEIGHTS'].sum() != 0 else np.nan ) agg_dict = {'DRESS_AMT': 'max', 'FACE_AMT': 'sum', 'Other_AMT': {'weighted_mean' : wm}} df2 = df.groupby(['ID','COL1'], as_index=False).agg(agg_dict)
小提示
- 返回
np.nan是比较推荐的做法,因为pandas对缺失值有成熟的处理工具(比如fillna()、dropna()),可以根据后续业务需求灵活处理。 - 如果业务上权重总和为0是不应该出现的异常情况,可以在函数里抛出自定义异常,方便排查问题。
内容的提问来源于stack exchange,提问作者babz
相关产品推荐
相关产品推荐

