多列加权平均计算报错:TypeError: unhashable type: 'list'
问题:Pandas计算列加权平均时触发TypeError: unhashable type: 'list'
数据表格
| charge | (0.0, 1.0) | (0.0, 2.0) | (0.0, 3.0) |
|---|---|---|---|
| 84 | |||
| 116 | 1 | 10 | 147 |
| 226 | 9 | 842 | 342 |
| 343 | 2 | 278 | |
| 503 | 10 | ||
| 939 |
需求
计算上述表格中每一列的加权平均,权重列为charge。例如(0.0, 1.0)列的加权平均应为357.54。
错误代码及信息
代码
def weighted(x, cols, w="weights"): return pd.Series(np.average(x[cols], weights=x[w], axis=0), cols) FIN_A_PIV_Table.apply(weighted, ['(0.0, 1.0)','(0.0, 2.0)','(0.0, 3.0)'])
错误信息
File Q:\VDI\Python Source\Provider_Coder_Updated_v_Spyder.py:372 in <module> FIN_A_PIV_Table.apply(weighted, ['(0.0, 1.0)','(0.0, 2.0)','(0.0, 3.0)']) File C:\Research\lib\site-packages\pandas\core\frame.py:8839 in apply op = frame_apply( File C:\Research\lib\site-packages\pandas\core\apply.py:88 in frame_apply axis = obj._get_axis_number(axis) File C:\Research\lib\site-packages\pandas\core\generic.py:550 in _get_axis_number return cls._AXIS_TO_AXIS_NUMBER[axis] TypeError: unhashable type: 'list'
错误原因
DataFrame.apply()的第二个参数默认是axis(取值为0/1或'index'/'columns'),你直接传入列名列表,pandas会把这个列表当作axis参数解析,而列表是不可哈希类型,无法匹配_AXIS_TO_AXIS_NUMBER字典的键,因此触发错误。
解决方案
1. 正确传递自定义参数
使用apply()的args参数传递列名列表,注意args需要是元组类型:
FIN_A_PIV_Table.apply(weighted, args=(['(0.0, 1.0)','(0.0, 2.0)','(0.0, 3.0)'],))
2. 修正函数中的权重列参数与空值处理
原函数中w="weights"与实际权重列charge不符,需修改默认值,同时过滤空值避免np.average报错:
import pandas as pd import numpy as np def weighted(x, cols, w="charge"): # 过滤权重列和目标列均不为空的行 mask = x[w].notna() for col in cols: mask &= x[col].notna() filtered_data = x[mask] # 计算加权平均 avg_values = np.average(filtered_data[cols], weights=filtered_data[w], axis=0) return pd.Series(avg_values, index=cols) # 调用函数 result = FIN_A_PIV_Table.apply(weighted, args=(['(0.0, 1.0)','(0.0, 2.0)','(0.0, 3.0)'],)) print(result)
验证结果
(0.0, 1.0)列的计算:
有效数据加权和 = 1161 + 2269 + 3432 + 50310 = 7866
权重总和 = 1+9+2+10 = 22
加权平均 = 7866/22 ≈ 357.54,符合预期。
内容的提问来源于stack exchange,提问作者Raven
相关产品推荐
相关产品推荐

