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()