如何使用字典替换嵌套列表内层元素?解决numpy TypeError报错问题
解决numpy二维数组用字典替换元素的哈希错误问题
咱们先理清楚报错的根源:当你处理二维numpy数组时,直接用[ss_dict[i] for i in l]会把整个子数组当作字典的键去查找,但numpy数组是不可哈希的类型(unhashable),所以就抛出了TypeError: unhashable type: 'numpy.ndarray'——而一维数组时,遍历的是单个int元素,int是可哈希的,所以能正常工作。
下面给你几个可行的解决方案,按需选择:
方案1:嵌套列表推导式(最直观,新手友好)
既然是二维数组,咱们就逐层遍历到最内层的单个元素,再用字典替换:
import numpy as np ss_dict = { 1 : np.array([1,0,0,0,0,0]), 2 : np.array([0,1,0,0,0,0]), 3 : np.array([0,0,1,0,0,0]), 4 : np.array([0,0,0,1,0,0]), 5 : np.array([0,0,0,0,1,0]), 6 : np.array([0,0,0,0,0,1]), } # 二维输入数组示例 l = np.array([[1,2,3],[4,5,6]]) # 嵌套推导:先遍历每个子数组,再遍历子数组里的每个元素 l_replaced = np.array([[ss_dict[i] for i in sub_arr] for sub_arr in l]) print(l_replaced)
输出结果会是一个3维数组(每个原元素被替换成了6元素的数组):
[[[1 0 0 0 0 0] [0 1 0 0 0 0] [0 0 1 0 0 0]] [[0 0 0 1 0 0] [0 0 0 0 1 0] [0 0 0 0 0 1]]]
方案2:使用numpy的vectorize函数(适配多维场景)
如果以后还要处理更高维的数组,用np.vectorize把字典查找封装成向量化函数,自动帮你遍历所有元素:
# 定义向量化的替换函数,指定输出类型为ndarray vec_replace = np.vectorize(lambda x: ss_dict[x], otypes=[np.ndarray]) l_replaced = vec_replace(l) # 把结果整理成符合预期的形状(原二维数组+每个元素的6维长度) print(l_replaced.reshape(l.shape + (6,)))
这个方法不用管输入是1维、2维还是3维,都能自动适配,省得改推导式的层数。
方案3:利用numpy索引映射(最高效,适合大数据)
如果你的字典键是连续整数(比如这里是1-6),可以把字典的值整理成一个大数组,直接用索引替换,效率比列表推导式高很多:
# 把字典的值按键的顺序排列,索引和键对应(这里键从1开始,所以索引0放个占位的空数组) mapping_arr = np.array([ np.zeros(6), # 索引0,对应键0(如果不需要可以去掉,只要保证键n对应索引n就行) ss_dict[1], ss_dict[2], ss_dict[3], ss_dict[4], ss_dict[5], ss_dict[6] ]) # 直接用数组索引替换,numpy会自动处理多维数组的广播 l_replaced = mapping_arr[l] print(l_replaced)
这个方法是numpy原生优化过的操作,处理大规模数据时速度会快很多。
最后提醒一句:如果你的输入数组里可能存在不在字典键中的值,记得用ss_dict.get(i, 默认值)来避免KeyError哦~
内容的提问来源于stack exchange,提问作者lanselibai
相关产品推荐
相关产品推荐

