无法读取含嵌套元组多层索引DataFrame的Parquet文件
问题解答:Parquet保存含元组的多级索引报错问题
错误原因
你遇到的TypeError: unhashable type: 'numpy.ndarray',本质是因为Parquet格式存储多级索引时,会将索引中的元组转换为numpy数组。当读取文件时,pandas尝试将这些数组作为索引值,但numpy数组属于不可哈希类型,无法作为索引元素,因此触发错误。
可行解决方案
你有两种选择来解决这个问题:
方案1:重置索引后保存(最简便直接)
在保存到Parquet前,先将多级索引转换为普通列,读取后再重新设置索引:
# 保存时重置索引 df.reset_index().to_parquet("test.parquet") # 读取后恢复索引 df_read = pd.read_parquet("test.parquet").set_index(['level_0', 'level_1'])
这种方法无需修改索引结构,操作简单,适合大多数场景。
方案2:将索引元组转换为可哈希类型后保存
如果需要保留索引结构在Parquet中,可以先将索引里的元组转换为字符串(可哈希类型),读取后再转换回元组:
# 转换索引中的元组为字符串 df_index_converted = df.copy() df_index_converted.index = df_index_converted.index.set_levels( [level.map(str) for level in df.index.levels], level=['level_0', 'level_1'] ) # 保存到Parquet df_index_converted.to_parquet("test_converted.parquet") # 读取后转换回元组 df_read_converted = pd.read_parquet("test_converted.parquet") df_read_converted.index = df_read_converted.index.set_levels( [level.map(eval) for level in df_read_converted.index.levels], level=['level_0', 'level_1'] )
注意:使用eval转换字符串回元组时,要确保索引内容安全,避免恶意代码风险。
结论
Parquet本身不支持直接存储包含元组的多级索引(因为会被转为不可哈希的numpy数组),所以要么重置索引保存,要么先将元组转为可哈希类型再保存。重置索引是更稳妥、简便的方案。
内容的提问来源于stack exchange,提问作者fmc100
相关产品推荐
相关产品推荐

