单列数据集KMeans聚类后绘制散点图遇TypeError问题求助
解决KMeans聚类后绘制散点图的TypeError问题
问题根源分析
你遇到的TypeError: unhashable type: 'numpy.ndarray'主要来自三个问题:
- 错误的DataFrame索引逻辑:你的数据集只有单列(
Brim),但你用了df1[x ==1,0]这种numpy数组式的二维索引——pandas DataFrame不支持这种语法,它会把(x ==1, 0)当成带numpy数组的元组去匹配列名,而numpy数组是不可哈希的,直接触发报错。 - 无意义的第二列调用:你的数据只有一列,根本不存在索引为
1的列,df1[x == 0,1]这种写法完全不符合你的数据集结构。 - 冗余的聚类调用:你先执行了
km.fit(df1),之后又调用km.fit_predict(df1),其实fit_predict已经包含了模型训练步骤,重复调用纯粹是浪费计算资源。
修正方案
因为你的数据是单列的,绘制聚类散点图需要先构造x轴的数值(比如数据的位置索引),再用聚类标签区分颜色。具体步骤如下:
- 精简聚类代码,直接用
fit_predict获取聚类标签 - 用pandas合法的布尔索引提取对应聚类的数据
- 构造x轴(用数据索引或序列值),配合单列数据绘制散点图
完整修正代码
from sklearn.cluster import KMeans import numpy as np import matplotlib.pyplot as plt %matplotlib inline # 假设df1是你的单列DataFrame # 精简聚类步骤,直接获取聚类标签 km = KMeans(n_clusters=4, init='k-means++', n_init=10) cluster_labels = km.fit_predict(df1) # 构造x轴:使用数据的索引值 x_axis = df1.index.values # 获取Brim列的数值 y_axis = df1['Brim'].values # 按聚类标签绘制散点图 plt.scatter(x_axis[cluster_labels == 0], y_axis[cluster_labels == 0], s=100, c='red', label='Cluster 0') plt.scatter(x_axis[cluster_labels == 1], y_axis[cluster_labels == 1], s=100, c='black', label='Cluster 1') plt.scatter(x_axis[cluster_labels == 2], y_axis[cluster_labels == 2], s=100, c='blue', label='Cluster 2') plt.scatter(x_axis[cluster_labels == 3], y_axis[cluster_labels == 3], s=100, c='cyan', label='Cluster 3') # 添加图表标注 plt.xlabel('Data Index') plt.ylabel('Brim Value') plt.legend() plt.show()
另一种简化方式(转为numpy数组)
如果你觉得DataFrame索引麻烦,可以先把单列数据转为二维numpy数组(sklearn的KMeans要求输入是二维数组),直接用数组索引操作:
# 转为二维numpy数组 data = df1.values km = KMeans(n_clusters=4, init='k-means++', n_init=10) cluster_labels = km.fit_predict(data) # 用序列值作为x轴 plt.scatter(np.arange(len(data))[cluster_labels == 0], data[cluster_labels == 0], s=100, c='red') plt.scatter(np.arange(len(data))[cluster_labels == 1], data[cluster_labels == 1], s=100, c='black') plt.scatter(np.arange(len(data))[cluster_labels == 2], data[cluster_labels == 2], s=100, c='blue') plt.scatter(np.arange(len(data))[cluster_labels == 3], data[cluster_labels == 3], s=100, c='cyan') plt.show()
这样就能正常绘制出聚类后的散点图,不会再触发TypeError了。
内容的提问来源于stack exchange,提问作者anagha s
相关产品推荐
相关产品推荐

