python一直报错

报错unhashable type: 'numpy.ndarray',想问问怎么改哇!

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
df=pd.read_excel('/Users/mac/Desktop/实验七  数据包(1)/B39.xlsx')
plt.rcParams['font.sans-serif']=['Songti SC']
labels=np.array(['食品支出','衣着支出','居住','家庭设备及用品','医疗保健','交通和通信','文教娱乐服务','其他'])
dataLenth=6
df1=np.array(df[df['地区']=='北京'])
df2=np.array(df[df['地区']=='天津'])
df3=np.array(df[df['地区']=='上海'])
df4=np.array(df[df['地区']=='重庆'])
angles=np.linspace(0,2*np.pi,dataLenth,endpoint=False)
df1=np.concatenate((df1,[df1[0]]))
df2=np.concatenate((df2,[df2[0]]))
df3=np.concatenate((df3,[df3[0]]))
df4=np.concatenate((df4,[df4[0]]))
angles=np.concatenate((angles,[angles[0]]))
plt.polar(angles,df1,color='r',linestyle='-',marker='v',linewidth=2,label='北京')
plt.fill(angles,df1,facecolor='r',alpha=0.5)
plt.polar(angles,df2,color='c',linestyle='--',marker='+',linewidth=2,label='天津')
plt.fill(angles,df2,facecolor='c',alpha=0.5)
plt.polar(angles,df3,color='purple',linestyle='-·',marker='s',linewidth=2,label='上海')
plt.fill(angles,df3,facecolor='purple',alpha=0.5)
plt.polar(angles,df4,color='gray',linestyle=':',marker='p',linewidth=2,label='重庆')
plt.fill(angles,df4,facecolor='gray',alpha=0.5)
plt.thetagrids(range(0,360,45),labels)
plt.ylim(0,10000)
plt.legend(loc='upper right',bbox_to_anchor=(1.2,1.1))
plt.show()

img

这个错误出现在多数情况下都是由于 numpy.ndarray 类型的数据不能被哈希(hash)而引起的。

在你的代码中,出现 "unhashable type: 'numpy.ndarray'" 错误的原因是,你在用 numpy.array 函数将 pandas.DataFrame 数据转化为 numpy.ndarray 类型时,得到的 ndarray 类型数据不可哈希,因此无法作为字典的键(例如 plt.fill 函数中),从而引发了错误。

在这里,我们可以将 numpy.ndarray 类型数据转换成 python 内建的 list (可以被哈希),再作为函数参数输入即可,方法是:

df1 = df1.tolist()
df2 = df2.tolist()
df3 = df3.tolist()
df4 = df4.tolist()

这些操作将 df1, df2, df3 和 df4 的数据类型从 numpy.ndarray 转化为 list,之后就可以正常地使用 plt.fill 函数了。

以下是修改后的代码:

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

df = pd.read_excel('/Users/mac/Desktop/实验七  数据包(1)/B39.xlsx')
plt.rcParams['font.sans-serif'] = ['Songti SC']
labels = np.array(['食品支出', '衣着支出', '居住', '家庭设备及用品', '医疗保健', '交通和通信', '文教娱乐服务', '其他'])
dataLenth = 6
df1 = np.array(df[df['地区'] == '北京'])
df2 = np.array(df[df['地区'] == '天津'])
df3 = np.array(df[df['地区'] == '上海'])
df4 = np.array(df[df['地区'] == '重庆'])
angles = np.linspace(0, 2 * np.pi, dataLenth, endpoint=False)
df1 = np.concatenate((df1, [df1[0]]))
df2 = np.concatenate((df2, [df2[0]]))
df3 = np.concatenate((df3, [df3[0]]))
df4 = np.concatenate((df4, [df4[0]]))
angles = np.concatenate((angles, [angles[0]]))

# 转换 ndarary 数据类型为 list
df1 = df1.tolist()
df2 = df2.tolist()
df3 = df3.tolist()
df4 = df4.tolist()

plt.polar(angles, df1, color='r', linestyle='-', marker='v', linewidth=2, label='北京')
plt.fill(angles, df1, facecolor='r', alpha=0.5)

plt.polar(angles, df2, color='c', linestyle='--', marker='+', linewidth=2, label='天津')
plt.fill(angles, df2, facecolor='c', alpha=0.5)

plt.polar(angles, df3, color='purple', linestyle='-·', marker='s', linewidth=2, label='上海')
plt.fill(angles, df3, facecolor='purple', alpha=0.5)

plt.polar(angles, df4, color='gray', linestyle=':', marker='p', linewidth=2, label='重庆')
plt.fill(angles, df4, facecolor='gray', alpha=0.5)

plt.thetagrids(range(0, 360, 45), labels)
plt.ylim(0, 10000)
plt.legend(loc='upper right', bbox_to_anchor=(1.2, 1.1))
plt.show()

希望这个回答对你有所帮助。

该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
报错信息 "unhashable type: 'numpy.ndarray'" 通常是由于出现了不可哈希的对象,比如 numpy 数组,而这些对象无法作为字典的键值或集合的元素。

在你的代码中,使用了 Numpy 库中的数组,例如:

labels=np.array(['食品支出','衣着支出','居住','家庭设备及用品','医疗保健','交通和通信','文教娱乐服务','其他'])

以及:

df1=np.array(df[df['地区']=='北京'])
df2=np.array(df[df['地区']=='天津'])
df3=np.array(df[df['地区']=='上海'])
df4=np.array(df[df['地区']=='重庆'])

这些数组可能是导致错误的原因之一。由于 plt.polar() 方法需要传递可哈希对象作为参数,因此你需要将这些数组转换成可哈希对象。可以使用 tuple() 方法将 Numpy 数组转换成元组(tuple):

labels = tuple(['食品支出', '衣着支出', '居住', '家庭设备及用品', '医疗保健', '交通和通信', '文教娱乐服务', '其他'])

以及:

df1 = tuple(df[df['地区']=='北京'].values.flatten())
df2 = tuple(df[df['地区']=='天津'].values.flatten())
df3 = tuple(df[df['地区']=='上海'].values.flatten())
df4 = tuple(df[df['地区']=='重庆'].values.flatten())

此外,你还需要将 angles 数组转换成可哈希对象。可以使用 tuple() 方法将 Numpy 数组转换成元组(tuple):

angles = tuple(np.linspace(0, 2*np.pi, dataLenth, endpoint=False))

这些修改后的代码如下所示:

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

df = pd.read_excel('/Users/mac/Desktop/实验七  数据包(1)/B39.xlsx')

plt.rcParams['font.sans-serif']=['Songti SC']
labels = tuple(['食品支出', '衣着支出', '居住', '家庭设备及用品', '医疗保健', '交通和通信', '文教娱乐服务', '其他'])
dataLenth = 6

df1 = tuple(df[df['地区']=='北京'].values.flatten())
df2 = tuple(df[df['地区']=='天津'].values.flatten())
df3 = tuple(df[df['地区']=='上海'].values.flatten())
df4 = tuple(df[df['地区']=='重庆'].values.flatten())
angles = tuple(np.linspace(0, 2*np.pi, dataLenth, endpoint=False))

df1 = np.concatenate((df1, [df1[0]]))
df2 = np.concatenate((df2, [df2[0]]))
df3 = np.concatenate((df3, [df3[0]]))
df4 = np.concatenate((df4, [df4[0]]))
angles = np.concatenate((angles, [angles[0]]))

plt.polar(angles, df1, color='r', linestyle='-', marker='v', linewidth=2, label='北京')
plt.fill(angles, df1, facecolor='r', alpha=0.5)
plt.polar(angles, df2, color='c', linestyle='--', marker='+', linewidth=2, label='天津')
plt.fill(angles, df2, facecolor='c', alpha=0.5)
plt.polar(angles, df3, color='purple', linestyle='-·', marker='s', linewidth=2, label='上海')
plt.fill(angles, df3, facecolor='purple', alpha=0.5)
plt.polar(angles, df4, color='gray', linestyle=':', marker='p', linewidth=2, label='重庆')
plt.fill(angles, df4, facecolor='gray', alpha=0.5)

plt.thetagrids(range(0, 360, 45), labels)
plt.ylim(0, 10000)
plt.legend(loc='upper right', bbox_to_anchor=(1.2, 1.1))
plt.show()

希望这能帮助你解决问题。


如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

加油。

  • 这篇博客也许可以解决你的问题👉 :TypeError: unhashable type: 'numpy.ndarray'
  • 除此之外, 这篇博客: 编程过程中遇到bug解决方案中的 3、成功解决TypeError: unhashable type: ‘numpy.ndarray’ 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 解决方法
    总结网友以及博主的思路,如下:
    T1、先尝试修改变量名:看到莫名其妙的TypeError要考虑是否存在变量名重复,或者是由于变量名与占位符名冲突导致的。
    T2、转为numpy数组:因为得到的X_test_label,其实是 DataFrame格式,故该格式是不能用于迭代的。尝试可将其转化成 np.array 格式的,如 X_train = np.array(X_train)
    X_test_label=np.array(X_test_label)
    T3、如果还出现,此时就要采用,在T2的基础上,对array类型数组进行全部[取0]

  • 以下回答由chatgpt基于相关博客总结生成:

    该错误提示“unhashable type: 'numpy.ndarray'”是因为numpy.ndarray类型的元素不可哈希,无法作为字典的键(字典的键必须是可哈希的)。因此在使用字典时,如果值包含numpy数组这种类型,则会出现这个错误。

    解决这个问题的方法有两种:一是尝试使用其他数据类型替换numpy数组;二是对numpy数组做一些处理,使其变成可哈希的类型。具体方法如下:

    1. 使用其他数据类型替换numpy数组:如果程序中并不需要使用numpy数组的某些特性,也可以将其转换成其他数据类型,如列表或元组。例如,如果字典的值是由一组数组组成的列表,则可以将其中的每个数组转换成元组,这样就可以避免出现unhashable错误。具体代码如下:
    import numpy as np
    
    # 创建一个字典,其中包含numpy数组类型的值
    d = {'a': np.array([1, 2, 3]), 'b': np.array([4, 5,6])}
    
    # 将每个数组转换成元组类型
    d = {k: tuple(v) for k, v in d.items()}
    
    1. 将numpy数组转换成可哈希的类型:如果程序中需要使用到numpy数组的一些特性,例如多维数组的运算,那么可以将数组转换成元组或字符串等可哈希类型。具体做法可以参考以下代码:
    import numpy as np
    
    # 创建一个包含numpy数组的元组
    t = (np.array([1, 2, 3]), np.array([4, 5, 6]))
    
    # 将元组中的每个数组都转换成元组类型
    t = tuple(tuple(x) for x in t)
    
    # 将数组转换成字符串
    s = str(np.array([1, 2, 3]))
    

    在处理numpy数组时,还需要注意以下几点:

    • 在创建numpy数组时,可以通过指定dtype参数来指定数组元素的数据类型。例如,可以将整型数组的dtype设置为np.int8、np.int16等来减小其内存占用。如果不指定dtype参数,则numpy将自动根据数据的情况选择数据类型。例如,如果数组中有浮点数,则numpy将自动将dtype设置为float64。

    • 在使用numpy数组进行数学计算时,需要注意数组的shape属性。如果两个数组的shape不一致,则可能会出现维度不匹配的错误。可以使用reshape方法来调整数组的形状,使其适合计算需求。

    • 可以使用axis参数来指定对某一维度进行行或列的操作,例如计算平均值。如果axis=0,则表示对列进行操作,返回每行的平均值。如果axis=1,则表示对行进行操作,返回每列的平均值。具体代码如下:

    import numpy as np
    
    # 创建一个包含语文、数学、英语成绩的2行3列数组
    scores = np.array([[80, 90, 70], [85, 95, 75]])
    
    # 计算每个科目的平均分,axis=0表示对每列进行操作
    mean_scores = np.mean(scores, axis=0)
    print(mean_scores)  # 输出结果为 [82.5 92.5  72.5]