1 import pandas as pd 2 import numpy as np 3 import matplotlib.pyplot as plt 4 from sklearn.cluster import KMeans 5 6 7 def build_data(): 8 """ 9 构建数据 10 :return:原始数据 11 """ 12 nba_data = pd.read_excel("./nba_data.xlsx") 13 14 return nba_data 15 16 17 def deal_data(nba_data): 18 """ 19 数据处理 20 :param nba_data: 待处理数据 21 :return: 数据处理之后的nba_data 22 """ 23 # 1、筛选相关特征 24 nba_data = nba_data.loc[:, ["时间", "助攻", "得分"]] 25 # 2、检测缺失值 26 res_null = pd.isnull(nba_data).sum() 27 print("缺失值检测结果:\n", res_null) 28 # 3、处理缺失值 29 # 将 时间列的 " " 先转化为np.nan类型,再进行缺失值处理 30 nba_data.replace(" ", np.nan, inplace=True) 31 # print("转化之后缺失值检测结果:", pd.isnull(nba_data).sum()) 32 # 对缺失值进行 处理---??? 33 # (1)删除---会损失大量数据 34 # (2)拉格朗日插值---时间可能会插上负值,有的数据还特别大 35 # (3)填充---均值、众数、中位数、上下邻居 36 # 计算众数 37 mode = nba_data.loc[:, "时间"].mode()[0] 38 # 填充 39 nba_data.loc[:, "时间"].fillna(value=mode, inplace=True) 40 print("转化之后缺失值检测结果:", pd.isnull(nba_data).sum()) 41 # 4、构建最终的特征 42 # 检测各个特征的数据类型 43 res_dtype = nba_data.dtypes 44 print("各个特征的数据类型:\n", res_dtype) 45 # 46 # # 将时间转化为float 类型 47 nba_data.loc[:, "时间"] = nba_data.loc[:, "时间"].astype(np.float64) 48 # # 49 # print("数据类型转化之后的结果:\n", nba_data.dtypes) 50 nba_data.loc[:, "得分/分钟"] = nba_data.loc[:, "得分"] / nba_data.loc[:, "时间"] 51 nba_data.loc[:, "助攻/分钟"] = nba_data.loc[:, "助攻"] / nba_data.loc[:, "时间"] 52 53 nba_data = nba_data.loc[:, ["得分/分钟", "助攻/分钟"]] 54 print("特征构建之后的结果:\n", nba_data) 55 # 5、处理异常值---数据正常不需要异常值处理 56 print("分钟得分的最大值、最小值", nba_data.loc[:, "得分/分钟"].max(), nba_data.loc[:, "得分/分钟"].min()) 57 print("助攻得分的最大值、最小值", nba_data.loc[:, "助攻/分钟"].max(), nba_data.loc[:, "助攻/分钟"].min()) 58 # 6、标准化数据---量级相差不大,不需要标准化 59 60 return nba_data 61 62 63 def km_fit(nba_data, k): 64 """ 65 nba球员聚类 66 :param nba_data: 数据 67 :param k: 聚类的类别数目 68 :return: 69 """ 70 # 1、创建算法实例 71 km = KMeans(n_clusters=k) 72 # 2、训练数据 73 km.fit(nba_data) 74 # 3、预测 75 y_predict = km.predict(nba_data) 76 77 # 获取聚类中心 78 center = km.cluster_centers_ 79 80 return y_predict, center 81 82 83 def show_res(nba_data, y_predict, center): 84 """ 85 结果展示 86 :param nba_data: 数据 87 :param y_predict: 预测值 88 :param center: 聚类中心 89 :return: None 90 """ 91 # 1、创建画布 92 plt.figure() 93 # 2、绘图 94 color_list = ["r", "g", "pink", "y", "k"] 95 # 散点图 96 for i in range(nba_data.shape[0]): 97 plt.scatter(nba_data[i, 0], nba_data[i, 1], c=color_list[y_predict[i]]) 98 99 print("nba_data: ", nba_data) 100 print("nba_data.shape[0]: ", nba_data.shape[0]) 101 print("nba_data[i, 0]: ", nba_data[i, 0]) 102 print("nba_data[i, 1]: ", nba_data[i, 1]) 103 104 # 绘制标注 105 plt.plot(center[:, 0], center[:, 1], "bx", markersize=12) 106 # 3、展示 107 plt.show() 108 109 110 def main(): 111 """ 112 主函数 113 :return: 114 """ 115 # 1、加载数据 116 nba_data = build_data() 117 print("nba_data:\n", nba_data) 118 print("nba_data 的列索引:\n", nba_data.columns) 119 120 # 2、数据处理 121 nba_data = deal_data(nba_data) 122 123 # 3、聚类分析 124 # 确定聚类类别数目 125 k = 5 126 y_predict, center = km_fit(nba_data, k) 127 128 print("预测值:\n", y_predict) 129 print("聚类中心:\n", center) 130 131 # 4、结果展示 132 show_res(nba_data.values, y_predict, center) 133 134 135 if __name__ == '__main__': 136 main()