pandas.Series.mean()不支持加权,需用np.average(s.values, weights=w)或df.dot(w)/w.sum();注意索引对齐、NaN处理及权重归一化。

用 pandas.Series.mean() 直接加权?不行,得自己算
pandas.Series.mean() 和 DataFrame.mean() 都不支持 weights 参数。这不是遗漏,而是设计取舍——Pandas 把加权逻辑留给用户控制,避免隐式行为(比如权重未归一化时结果难解释)。所以必须手动组合计算:用 Series.dot() 或 np.average() 配合 Series.values。
最稳妥的做法:用 numpy.average() + Series.values
这是兼容性最好、语义最清晰的方式,尤其适合单列加权均值。注意三点:
-
numpy.average()的weights参数要求与数据等长,且自动归一化(即权重和不影响结果) - 传入
Series.values而非原Series,避免索引对齐干扰(比如两列索引顺序不一致时) - 若数据含
NaN,需先用dropna()并同步过滤权重,否则报错或结果异常
示例:
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
import pandas as pd import numpy as np <p>s = pd.Series([10, 20, 30]) weights = [1, 2, 3]</p><h1>正确:显式对齐、去 NaN</h1><p>valid_mask = s.notna() result = np.average(s[valid_mask].values, weights=weights[valid_mask])</p>
想在 DataFrame 多列上批量加权?别循环,用 dot() + 归一化权重
当每行有多个指标、每列对应不同权重(比如考试中语文权重 0.4、数学 0.6),用 df.dot(weights) 最高效。但要注意:
-
weights必须是pd.Series,索引与df.columns完全匹配,否则静默对齐失败(缺失列被填 0) -
dot()不归一化权重,结果是加权和;如需加权平均,得除以权重和:df.dot(weights) / weights.sum() - 如果某行存在
NaN,dot()默认返回NaN,无法跳过——必须提前用fillna()或掩码处理
示例:
df = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
w = pd.Series({'A': 0.3, 'B': 0.7})
<p>weighted_sum = df.dot(w) # → [3.0, 3.4]
weighted_mean = df.dot(w) / w.sum() # 同上,因 w.sum()==1</p>
为什么不用 apply() 配合 np.average?性能差且易出错
有人会写 df.apply(lambda x: np.average(x, weights=w), axis=1),这看似直观,但问题明显:
-
axis=1下,x是Series,其索引与w索引若不一致,np.average会按位置而非标签对齐,导致权重错配 -
apply是 Python 循环,大数据量下比向量化dot()慢 5–10 倍 - 遇到
NaN时,np.average默认抛RuntimeWarning,而dot()行为更可预测
真正要灵活处理缺失值+权重+多列,优先构造布尔掩码再切片计算,而不是依赖 apply 的“自动”行为。
加权平均本身不复杂,但 Pandas 里容易栽在索引对齐、NaN 传播和权重归一化这三个点上。动手前先 print 一下权重和数据的索引、长度、是否含空值,比硬试快得多。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










