
本文介绍如何基于字典定义的权重,对 dataframe 中指定列执行逐行加权求和,并将结果作为新列高效添加,避免硬编码计算,提升可维护性与扩展性。
在数据分析中,经常需要根据业务规则为不同指标赋予权重(如篮球统计中得分 pts 权重为 1、篮板 reb 为 1.2、助攻 ast 为 1.5、失误 tov 为 −1),再对各行进行加权求和生成综合评分(如 score)。若手动编写 df['pts'] * 1 + df['reb'] * 1.2 + ...,不仅冗长易错,且权重变更时需多处修改。更优雅的方式是利用 Pandas 内置的 .dot() 方法,结合字典构建权重向量,实现声明式、可配置的加权计算。
核心思路是:将权重字典转换为 pd.Series,其索引对应目标列名;再调用 df[columns].dot(weights),Pandas 会自动按列名对齐并执行行级点积(即每行各列值 × 对应权重,再求和)。
以下为完整实现示例:
import pandas as pd
# 原始数据
df = pd.DataFrame({
'id': [1, 2, 3],
'pts': [25, 20, 9],
'ast': [8, 14, 7],
'reb': [1, 4, 9],
'oth': [5, 6, 7], # 不参与加权(字典中未定义)
'tov': [4, 2, 1]
})
# 权重字典:仅对需参与计算的列定义系数
score_dict = {'pts': 1.0, 'reb': 1.2, 'ast': 1.5, 'tov': -1.0}
# 构建权重 Series(关键:索引必须与目标列名完全一致)
weights = pd.Series(score_dict)
# 执行加权求和 → 自动对齐列名,忽略字典中不存在的列(如 'oth'、'id')
# 注意:只传入字典中出现的列,确保安全对齐
target_cols = list(score_dict.keys())
df['score'] = df[target_cols].dot(weights)
print(df)输出:
id pts ast reb oth tov score 0 1 25 8 1 5 4 34.2 1 2 20 14 4 6 2 43.8 2 3 9 7 9 7 1 29.3
✅ 优势说明:
- 健壮对齐:.dot() 严格依据列名(而非位置)匹配权重,即使列顺序变动或存在无关列(如 id、oth)也不影响结果;
- 零依赖循环:纯向量化运算,性能优于 apply() 或 map();
- 高可维护性:权重集中管理在字典中,增删列或调整系数只需修改 score_dict;
- 天然容错:若某列在 DataFrame 中缺失,.dot() 会报 KeyError,便于早期发现数据异常。
⚠️ 注意事项:
- 确保 score_dict 的键全部存在于 df.columns 中,否则会引发 KeyError;可预先校验:assert all(k in df.columns for k in score_dict);
- 若需支持缺失列默认权重为 0,可改用 df.reindex(columns=list(score_dict.keys()), fill_value=0).dot(weights);
- 避免直接对含非数值列(如字符串 ID)的整个 DataFrame 调用 .dot(),务必显式筛选目标数值列。
通过这一方法,你不仅能简洁实现加权评分逻辑,还能为后续接入配置文件(如 YAML/JSON 权重表)或动态策略引擎打下坚实基础。










