Pandas按含numpy.ndarray的列分组报Unhashable异常及异常被忽略原因咨询
报错的直接触发原因
你用于分组的A列元素是不可哈希的numpy.ndarray类型。pandas做分组、索引值映射时,核心依赖对每个元素计算哈希值来快速定位分组、匹配索引,但numpy数组本身没有实现可哈希的协议,无法生成唯一的哈希标识,因此触发了TypeError: unhashable type: 'numpy.ndarray'报错。
为什么异常会被提示“已忽略”,还能正常返回结果Series
- 报错的代码路径不属于主流程的核心阻断环节。你看到的异常栈来自
pandas._libs.index.IndexEngine._call_map_locations,这部分是pandas在聚合主逻辑跑完后,用于给结果索引做性能优化的后置逻辑——具体是给索引元素预生成哈希表,方便后续快速做索引值查找的优化步骤。 - 这部分由Cython层实现的优化逻辑,在设计上就做了降级处理:如果优化环节因为元素不可哈希运行失败,不会中断整个任务,也不会丢弃已经计算完成的主结果,只会把这个非核心环节抛出的异常捕获后打印提示,也就是你看到的“Exception ignored in: ...”的输出,不会让整个程序崩溃。
- 你的核心groupby统计流程、结果Series的基础结构其实已经全部生成完成了,不会因为这个后置优化环节的失败被销毁。
为什么生成的Series索引是numpy数组类型
pandas在构建结果索引时,本来需要对A列的每个元素做哈希校验、去重来生成标准的可哈希索引,但因为元素是不可哈希的numpy数组,校验流程走不通,pandas会直接将原A列的numpy数组对象原样作为索引值塞进Series,相当于跳过了正常的索引构建校验步骤,最终你看到的Series索引里的元素就是原始的numpy数组对象。
这个场景下的隐藏问题
不要因为程序返回了结果就认为分组统计是正确的。因为numpy数组不可哈希,哪怕两个数组的数值内容完全一致,pandas也无法通过哈希判定它们属于同一个分组,最后生成的统计结果会把每个numpy数组对象单独算一组,根本不会把内容相同的数组合并统计,最终得到的去重姓名计数会和预期存在明显偏差。
如果要正确计算,只需要把A列的numpy数组转成可哈希的元组形式,比如对每个数组执行tuple(array)转换,就可以正常触发分组逻辑、正确匹配同内容的数组组,也不会触发相关报错。
内容的提问来源于stack exchange,提问作者Ethan Gomez
相关产品推荐
相关产品推荐

