Python用pandas处理温度数据时遇TypeError: unhashable type: 'list'求助
问题分析与修正方案
嘿,我来帮你拆解这个TypeError: unhashable type: 'list'的问题,顺便理顺你的代码逻辑:
错误原因拆解
索引误用导致类型冲突
你创建的peak是一个一维布尔Series(来自df.iloc[-1] < pctl,只对应DataFrame最后一行的比较结果),但你在循环里试图用二维索引[i, averages]去访问它——Series是一维结构,根本不支持这种二维索引方式。更关键的是,averages是一个列表,当你错误地把它塞进loc索引时,Python会尝试将列表作为哈希键使用,但列表是不可哈希(unhashable)的类型,这直接触发了报错。逻辑偏差
原代码里peak只计算了最后一行的比较结果,但循环却遍历了所有行,这显然和你“检查任一平均温度峰值是否满足条件”的需求不匹配。
修正方案
步骤1:缩小分位数计算范围
先只针对你关心的T1avg和T2avg列计算分位数,避免不必要的计算:
import numpy as np import pandas as pd # 假设df是你的目标DataFrame df['T1avg'] = df['T1'].rolling(11, center=True).mean().shift(50) df['T2avg'] = df['T2'].rolling(11, center=True).mean().shift(50) averages = ['T1avg','T2avg'] # 仅针对目标列计算1%分位数,避免全表计算浪费资源 pctl = np.nanpercentile(df[averages], 1, axis=0)
步骤2:生成每行的布尔判断结果
如果你想检查每一行的平均温度是否低于对应列的1%分位数,应该生成一个布尔DataFrame(而非仅针对最后一行):
# 生成每行的布尔判断结果,得到一个shape为(len(df), 2)的DataFrame peak_mask = df[averages] < pctl
步骤3:检查峰值条件(两种方式任选)
方式一:批量判断(推荐,效率更高)
不需要循环,直接用any(axis=1)批量判断哪些行满足“至少一个平均温度低于1%分位数”的条件:
# 获取所有满足条件的行的布尔索引 peak_rows = peak_mask.any(axis=1) # 查看满足条件的行数据 print(df[peak_rows])
方式二:循环遍历(仅当你确实需要逐行处理时使用)
如果因为业务逻辑必须逐行处理,可以这样写:
for idx, row in df.iterrows(): # 检查当前行的两个平均温度是否有低于对应分位数的情况 if (row[averages] < pctl).any(): print(f"行{idx}满足峰值条件") # 在这里添加你需要执行的后续逻辑
额外提醒
你在滚动均值后使用了shift(50),这会导致前50行的T1avg/T2avg为NaN,np.nanpercentile会自动忽略这些NaN值,这部分是没问题的,但如果需要提前清理缺失值,可以用df[averages].dropna()处理。
内容的提问来源于stack exchange,提问作者Frank Abraham
相关产品推荐
相关产品推荐

