如何在Pandas中计算排除NaN影响的加权平均值
修正含NaN的DataFrame加权平均计算代码
原始数据
含NaN的DataFrame:
1 100 200 300 2 150 250 nan 3 175 275 375
权重Series(索引与DataFrame一致,无NaN):
1 3 2 4 3 7
需求说明
计算各列的加权平均值,需满足:
- 不将NaN视为0,直接忽略NaN所在行的计算
- 分母为对应列中非NaN值所在行的权重之和(例如第三列的有效权重和为3+7=10,而非总权重14)
- 预期输出:
1 151.79 2 251.79 3 352.5
当前代码问题
你当前的代码df.mul(s,axis=0).sum()/s.sum()错误地使用了所有权重的总和14作为分母,没有针对每列筛选出有效权重(非NaN行对应的权重)求和,导致第三列结果不符合预期。
修正后的代码
# 计算每列的加权数值总和(自动忽略NaN) weighted_sum = df.mul(s, axis=0).sum(axis=0) # 计算每列的有效权重总和(仅统计非NaN行的权重) valid_weight_sum = df.notna().mul(s, axis=0).sum(axis=0) # 计算最终加权平均值 result = weighted_sum / valid_weight_sum # 可选:保留两位小数匹配预期输出格式 result = result.round(2)
代码解释
df.mul(s, axis=0).sum(axis=0):将DataFrame的每个元素与对应行的权重相乘,再按列求和——由于NaN参与运算时会被自动忽略,得到的是每列有效数值的加权总和。df.notna().mul(s, axis=0).sum(axis=0):先将DataFrame转换为布尔矩阵(非NaN值为True,NaN为False),再与对应行的权重相乘,最后按列求和,得到每列的有效权重总和。- 两者相除即得到符合要求的加权平均值,使用
round(2)可以将结果保留两位小数,与预期输出一致。
运行结果
执行修正后的代码会得到:
0 151.79 1 251.79 2 352.50 dtype: float64
内容的提问来源于stack exchange,提问作者Sarthak Agrawal
相关产品推荐
相关产品推荐

