最近在看《Python数据分析与挖掘实战》,发现虽然书中的部分错误被改正,但是还有小错需要注意,尤其是看到第四章代码清单4-3 数据离散化。书中内容就不说了,自己看,直接上程序。
书中代码运行后直接提示错误:
#-*- coding: utf-8 -*-
#数据规范化
import pandas as pd
datafile = '../data/discretization_data.xls' #参数初始化
data = pd.read_excel(datafile) #读取数据
data = data[u'肝气郁结证型系数'].copy()
k = 4
d1 = pd.cut(data, k, labels = range(k)) #等宽离散化,各个类比依次命名为0,1,2,3
#等频率离散化
w = [1.0*i/k for i in range(k+1)]
w = data.describe(percentiles = w)[4:4+k+1] #使用describe函数自动计算分位数
w[0] = w[0]*(1-1e-10)
d2 = pd.cut(data, w, labels = range(k))
from sklearn.cluster import KMeans #引入KMeans
kmodel = KMeans(n_clusters = k, n_jobs = 4) #建立模型,n_jobs是并行数,一般等于CPU数较好
kmodel.fit(data.reshape((len(data), 1))) #训练模型
c = pd.DataFrame(kmodel.cluster_centers_).sort(0) #输出聚类中心,并且排序(默认是随机序的)
w = pd.rolling_mean(c, 2).iloc[1:] #相邻两项求中点,作为边界点
w = [0] + list(w[0]) + [data.max()] #把首末边界点加上
d3 = pd.cut(data, w, labels = range(k))
def cluster_plot(d, k): #自定义作图函数来显示聚类结果
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号
plt.figure(figsize = (8, 3))
for j in range(0, k):
plt.plot(data[d==j], [j for i in d[d==j]], 'o')
plt.ylim(-0.5, k-0.5)
return plt
cluster_plot(d1, k).show()
cluster_plot(d2, k).show()
cluster_plot(d3, k).show()
运行后直接提示错误:
C:\Users\Smile\PycharmProjects\untitled\venv\Scripts\python.exe H:/Pythondataana/chapter4/demo/code/4-3_data_discretization.py
Traceback (most recent call last):
File "H:/Pythondataana/chapter4/demo/code/4-3_data_discretization.py", line 20, in <module>
kmodel.fit(data.reshape((len(data), 1))) #训练模型
File "C:\Users\Smile\PycharmProjects\untitled\venv\lib\site-packages\pandas\core\generic.py", line 5067, in __getattr__
return object.__getattribute__(self, name)
AttributeError: 'Series' object has no attribute 'reshape'
经过百度,终于解决了此问题,更新后的代码:
# -*- coding: utf-8 -*-
# 数据离散化
import pandas as pd
datafile = '../data/discretization_data.xls' #参数初始化
data = pd.read_excel(datafile) # 读取数据
data = data[u'肝气郁结证型系数'].copy() # 将这一列的数据抓出来
k = 4 # 分成4个区间
d1 = pd.cut(data, k, labels=range(k)) # 等宽离散化,各个类比依次命名为0,1,2,3
# print d1
print(pd.value_counts(d1))
# 等频率离散化,qcut函数就是用来做按照分位数切割的
# 如果是分成4个区间,可以使用qcut函数,4表示按照4分位数进行切割
d2 = pd.qcut(data, 4, labels=range(k))
# print d2
print(pd.value_counts(d2))
# 如果想分成10个等份,则如下
w = [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]
d3 = pd.qcut(data, w, labels=range(10))
# print d3
print(pd.value_counts(d3))
# 也可以按照任意的分位数进行分割,使得每个区间按照自己设定的个数展示
w = [0, 0.1, 0.5, 0.9, 1]
d4 = pd.qcut(data, w, labels=range(4)) # labels是可以替换的,如:labels=['hao','zhong','yiban','huai']
# print d4
print(pd.value_counts(d4))
# 基于聚类的划分
from sklearn.cluster import KMeans # 引入KMeans
kmodel = KMeans(n_clusters=k, n_jobs=4) # 建立模型,n_jobs是并行数,一般等于CPU数较好
# kmodel.fit(data.reshape((len(data), 1))) #训练模型
kmodel.fit(data.values.reshape(-1, 1)) # 训练模型
# c = pd.DataFrame(kmodel.cluster_centers_).sort(0) #输出聚类中心,并且排序(默认是随机序的)
c = pd.DataFrame(kmodel.cluster_centers_).sort_values(0) # 输出聚类中心,并且排序(默认是随机序的)
# w = pd.rolling_mean(c, 2).iloc[1:] # 相邻两项求中点,作为边界点
w=c.rolling(2).mean().iloc[1:]
w = [0] + list(w[0]) + [data.max()] # 把首末边界点加上
d3 = pd.cut(data, w, labels=range(k))
def cluster_plot(d, k): # 自定义作图函数来显示聚类结果
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
plt.figure(figsize=(8, 3))
for j in range(0, k):
plt.plot(data[d == j], [j for i in d[d == j]], 'o')
plt.ylim(-0.5, k - 0.5)
return plt
cluster_plot(d1, k).show()
cluster_plot(d2, k).show()
cluster_plot(d3, k).show()
1 508
2 275
0 112
3 35
Name: 肝气郁结证型系数, dtype: int64
1 234
3 233
0 233
2 230
Name: 肝气郁结证型系数, dtype: int64
6 97
0 97
4 95
2 94
8 93
9 92
1 92
5 91
7 90
3 89
Name: 肝气郁结证型系数, dtype: int64
2 371
1 370
0 97
3 92
Name: 肝气郁结证型系数, dtype: int64