《Python数据分析与数据化运营》第一版 勘误
“本文为某Python数据分析出版物的官方勘误表与修正说明。共汇总42处错漏,全面涵盖代码规范(如Pandas与Sklearn的函数参数及用法)、文字拼写、统计学概念解释(如中位数、容忍度)以及业务逻辑公式(如提升度、客单价、RFM模型)的精准修正。旨在为读者提供准确的实操指导,相关错误将在后续版本中更正。”
出版物勘误表与修正说明
由于本书的作者水平有限并受限于有限的撰稿时间,以及整个出版环节众多可能会出现信息不对称,书中难免会出现一些错误或者不准确的地方,在此陈列出来供读者参考。这些已经发现的“错误”,会在下一次重印或再版时修正,有关修正的部分,会额外做标记,请读者朋友留意。
特别提示:由于第一版采用的仍然是 Python 2 代码,因此在 Python 2 下能正常工作,但是在 Python 3 下会出现的问题,不在此勘误列表内。
最近更新时间:2019-04-22
提示:在 2018 年 11 月的第一版第三次重印中,更新了部分问题,请读者留意。辨别购买版本的问题,请读者翻到如下页面的框选处:

勘误详情
1. P302 “5.8.4 案例过程——步骤 3 数据预处理” NA 值替换描述有误(2018.3 更已修正)
代码下面有一段如下的解释文字:
“功能实现过程中,先定义一个包括变量维度名称和对应的缺失值替换方法的字典,这里主要用到了均值 mean 和中位数 median,其中均值用于数值型变量,中位数用于字符串变量;接着用
df.fillna方法使用自定义的每列的不同方法批量替换缺失值;然后查看数据框中是否还存在缺失值并打印输出。”
其中“中位数用于字符串变量”的解释是错误的。原因是对于字符串变量而言,它是没有中位数的,它们只有 groupby 后的 count(计数)信息,即每个字符串的频数分布,而频数分布跟中位数是不一样的概念。
对于字符串的 NA 填充,由于没有更多统计性指标,通常有两种思路:
- 思路一:可以使用
count后的 TOP 值填充,但这种填充其实不符合真实情况。 - 思路二:将 NA 作为一个特殊的字符串分类值,参与到后续的变量计算中。例如,假如性别的取值是男和女,对于性别中的 NA 值,可以填充为“未知”或对应的英文字母。
2. 推荐语作者信息有误(2018.3 更已修正)
为本书写推荐语的两位大佬兴宝和郑来轶,兴宝老师的名字写错了,郑来轶老师的 Title 也已经变更。在此致歉!
3. P80 第四行文字重复(2018.3 更已修正)
本书的 P80 第四行,有一段这样的描述:“例如苹果 iPhone 7 属于个人电子消费品,这样才能将所有所有商品分配到唯一类别属性值中”,其中出现了两个“所有”,该重复会在重印时去掉。
4. P60 代码中 output 值写错(2018.3 更已修正)
本书的 P60 最下面有一段代码中的 output 值写错(备注:在 chapter2_code.py 中的代码是正确的,只是在粘贴到 Word 文稿时有问题)。
python
其中 output 后面的参数应该是 json,即:
python
否则无法返回下面的 JSON 字符串结果(其结果是以 key-value 形式存在的)。
5. P47 代码中 print 用法不规范
P47 的代码:
python
代码中的用法是 print something,其中 something 是要打印输出的对象。在本书的代码版本(Python 2.7)中,print 可以用两种方法:
python
第一种写法是早期版本的写法,可以直接 print 对象;后者是后期版本,也就是未来 Python 3 也兼容的版本。在后期版本中,print 是一个函数,而 something 是 print 的参数值。
在本书中,由于 2.7 的版本是兼容这两种写法的,因此这样写不会有问题。但是考虑到未来 Python 3 一定是方向,因此建议读者用后期写法。上面的代码应该更正为:
python
关于代码还是需要规范起来,不然在不同的版本做迁移或升级时,容易出问题,请大家引以为戒。
6. P53 关于 limit 的解释有误(2018.3 更已修正)
在“1)只查询前 N 条数据而非全部数据行记录”的解释中,有如下一段文字:
“知识点:LIMIT 为限制的数据记录数方法,语法为
limit m, n,意思是从第 m 到 n-1 条数据。”
其中,n-1 的描述有误,应该是从第 m 到 m+n 条数据,或从 m 开始偏移 n 条数据(也就是取 n 条数据)。
7. P39 关于 Numpy 中 float32 的精度描述有误(2018.3 更已修正)
在表 2-4 Numpy 数据类型中 float32 的描述中,其精度是 23 位,不是 32 位。
8. P54 使用正则表达式查询具有复杂条件的数据描述有误(2018.3 更已修正)
在“8) 使用正则表达式查询具有复杂条件的数据”中的示例描述中:“示例:查询 user_id 以 106 开头且 order_id 包含 04 的所有订单数据。”其中的 106 有误,应该为 103。
9. P83 sklearn 数据预处理方法描述有误(2018.3 更已修正)
在“第五部分通过 sklearn 的数据预处理方法对缺失值进行处理的内容”中,有一句:
“首先通过
Imputer方法创建一个预处理对象,其中 strategy 为默认缺失值的字符串,默认为 NaN”
其中的 strategy 应该为 missing_values,而 strategy 是缺失值替换方法的变量。
10. P82 sklearn 替换缺失值代码注释描述有误(2018.3 更已修正)
本段代码如下:
python
在上述代码中的第一段注释中“建立替换规则:将值为 Nan 的缺失值以均值做替换”,其中的 Nan 应该为 NaN(第三个字母大写)。严格意义上,'NaN' 和 'Nan' 是不同字符串,因此这里的描述应该跟代码中的 missing_values 的值一致。
11. P84 使用 Pandas 做缺失值处理示例举证颠倒(2018.3 更已修正)
在“第六部分使用 Pandas 做缺失值处理”解释文字中,有两行的示例举证颠倒:
pad和ffill:使用前面的值替换缺失值,示例中nan_result_pd1和nan_result_pd2使用了该方法。backfill和bfill:使用后面的值替换缺失值,示例中nan_result_pd3使用了该方法。
上面的描述中,示例中 nan_result_pd1 和 nan_result_pd2 使用的分别是 backfill 和 bfill,而 nan_result_pd3 使用的是 pad 方法。两段的示例应该颠倒过来。
12. P86 缺失值判断过程解释文字有误(2018.3 更已修正)
在“第三部分为缺失值判断过程”解释文字中,该段落的第一句有误。原文如下:
“第三部分为缺失值判断过程。本过程中,先通过
df.copy()复制一个原始数据框的副本用来存储 Z-Score 标准化后的得分...”
在该段落中,解释的是异常值,而非缺失值,因此本段的第一句应该为“第三部分为异常值判断过程”。
13. P117 容忍度的值域描述有误(2018.3 更已修正)
在关于“3.7.1 如何检验共线性”中容忍度的描述有如下一段文字:
“容忍度(Tolerance),容忍度是每个自变量作为因变量对其他自变量进行回归建模时得到的残差比例,大小用 1 减得到的决定系数来表示。容忍度的值介于 0.1 和 1 之间,如果值越小,说明这个自变量与其它自变量间越可能存在共线性问题。”
由于容忍度是 1 - R²(R 平方)得到的,而 R² 的值域是 [0, 1],因此容忍度的值域是 [0, 1],因此这里需要更正为“容忍度的值介于 0 和 1 之间”。
14. P262 会员营销指标中营销收入描述有误(2018.3 更已修正)
在关于“5.2.2 会员营销指标”中营销收入的描述中,有一段如下的描述:
“会员营销收入是通过会员营销渠道和会员相关运营活动产生的费用,包括电子邮件、短信、会员通知、线下二维码、特定会员优惠码等。”
其中“费用”应该更正为“收入”。
15. P130 Python 数据离散化处理描述有误(2018.3 更已修正)
在 P130 页底部关于“3.10.5 代码实操:Python 数据离散化处理”中第四部分“针对多值离散数据的离散化”的描述中,有如下一段文字:
“第四部分针对多值离散数据的离散化。该过程中先通过
dp.Dataframe定义一个新的转换区间,用来将原数据映射到新区间来;然后通过merge方法将原数据框和新定义的数据框进行关联,关联的两个 key(left_on和left_on)分别是age和age...”
其中的第二个 left_on 应该更正为 right_on。
16. P165 Python 聚类分析代码缺少分隔符(2018.3 更已修正)
在“4.1.6 代码实操:Python 聚类分析”代码段中,“打印输出指标值”一段代码缺少 \t 分隔符。
python
其中第一个打印字符串 %d 后面缺少 \t,所以导致 P168 的输出结果中,ine 和 ARI 的值没有间隔开。此段代码应该为:
python
17. P194 决策树规则解读数字错误(2018.3 更已修正)
在决策树解读(树形图下面第三行)有如下一段话:
“上述决策树规则显示了当
income <= 55654时,总样本量为 15348,其中负例样本和正例样本分别为 13700、1648。当income <= 55654且rfm_score <= 7.8375时,总样本量有 13581,其中负例样本和正例样本分别为 13700、881。以此类推可以读出其他的规则。”
其中的 13581 应为 14581。
18. P191 混淆矩阵中 TN/FP/FN 名称错误(2018.3 更已修正)
原文中对于 TP/TN/FP/FN 的解释如下:
表示分类正确:
- 真正(True Positive,TP):本来是正例,分类成正例。
- 假正(True Negative,TN):本来是负例,分类成负例。
表示分类错误:
- 假负(False Positive,FP):本来是负例,分类成正例。
- 真负(False Negative,FN):本来是正例,分类成负例。
其中:第二个 TN 应为真负、第三个 FP 应为假正、第四个 FN 应为假负。
19. P209 数据准备与异常结果统计代码有误(2018.3 更已修正)
在数据准备中有如下模块:
python
其中的 raw_data[:100, :] 应为 test_set = raw_data[900:, :] 取后 100 个数据。
在异常结果统计模块中,有如下部分的代码:
python
其中的 shape[1] 应该为 shape[0],这里取的是记录数量(行数)。
上面的两段代码变更后,对应的输出统计结果的部分,更改为:
code
20. P228 字符串解析为日期格式描述有误(2018.3 更已修正)
本段相关知识点中,有一句如下描述:
“pandas 中的 datetime 库是处理与日期相关主要功能库,其中的 strftime 用来将字符串解析为日期格式”
其中的 strftime 应为 strptime。
21. P166 模型应用中 predict 方法参数 shape 有误(2018.3 更已修正)
在 P166 的左上角代码块中,模型应用有一段如下的代码:
python
在上述运行过程中,由于 new_X 是一个点,其 shape 是一维的,而 predict 的数据要求是二维的,因此默认运行会报错。

因此,需要对 new_X 的 shape 做 reshape 操作。有两种方法:
方法一:直接加 []
python
方法二:先转换为 Numpy 数组,然后用 reshape 方法做转换
python
上面两种方法,从便捷程度上来讲,肯定是第一种更方便;从实际应用的“标准化”方向上,第二种更合适,因为这种用法可以相对更清晰地了解到底 new_X 的 shape 是怎样的;而第一种需要先向上寻找信息,去了解 new_X 的定义情况。大家各取所需,但就 1 个点的简单应用而言,第一种更合适。
跟这个问题类似的是 P176 “4.2.6 代码实操:Python 回归分析”中的“模型应用”和 P189 “4.3.6 代码实操:Python 分类分析”中的“模型应用”中的 predict 方法的应用。
在 P176 中的代码块中:
python
应该改为:
python
或:
python
在 P189 中的代码块中:
python
应该改为:
python
或:
python
22. P300 关于 df.isnull().any() 的解释有误(2018.3 更已修正)
在该页中,有一段如下的解释:
“使用
df.isnull().any()判断指定轴是否含有缺失值,当设置axis=0时以列为判断依据,当设置axis=0时以行为判断依据。”
其中第二个 axis=0 应改为 1,即当 axis=1 时以行为判断依据。
23. P216 pvalue1 和 pvalue2 与规则的对应有误(2018.3 更已修正)
在该页的刚开始有如下代码:
python
代码中,从白噪声检验和 ADF 检验得到的结果值中的 P 值分别为 pvalue1 和 pvalue2,这两个值下面的规则对应有误。正确的代码应该是:
python
24. P437 fillna 方法替换缺失值代码注释有误(2018.3 更已修正)
在 P437 中的中间靠上的部分,“步骤 4 数据预处理”中使用 fillna 方法将“平均停留时间”中的缺失值替换为均值的代码为:
python
代码注释中“用后面的值替换缺失值”应改为“用均值替换缺失值”。
25. P423 part6 代码块中的注释有误(2018.3 更已修正)
在本页中的下半部分,有一段如下的代码:
python
其中的注释错误,应该将“将分裂节点定义为增长最大值节点”改为“将分裂节点定义为增长最小值节点”。
26. P364 代码块中的注释有误(2018.3 更已修正)
本页中的代码第二行中的注释,应将“分割输入变量 X,并丢弃订单 ID 列和最后一列目标变量”改为“分割输入变量 X,并丢弃订单 ID 列”,即去掉其中的“和最后一列目标变量”,正确注释代码为:
python
27. P322 “4. 滞销金额”中的公式名称有误(2018.3 更已修正)
其中的公式“销售金额占比 = 滞销金额 / 库存金额”应该改为“滞销金额占比”。
28. P311 提示中的 Noen 拼写错误(2018.3 更已修正)
在描述文字中,有一段如下的文字:
“提示:使用
read_excel方法读取 Excel 时,可以通过参数sheetname定义要读取哪个 sheet 的数据,其值可以定义为 4 种,数值、字符串、数值和字符串的混合列表以及 Noen。其中数值代表 sheet 的索引值”
其中的 Noen,应该改为 None。
29. P348 描述文字中的 loos 拼写错误(2018.3 更已修正)
在描述文字中,有一段如下的文字:
“
loss:loos 是 GradientBoostingRegressor 的损失函数,主要包括四种 ls、lad、huber、quantile。ls(Least squares),默认方法,是基于最小二乘法方法的基本方法,也是普通线性回归的基本方法...”
其中的 loos 应该改为 loss。
30. P378 图 7-3 下面的描述文字有错别字(2018.3 更已修正)
其中有如下一段文字:
“服务器日志、在线其他系统数据以及离线数据也可以通过特定 FTP 服务器上传数据,具体流程为:企业内部通过程序生成特定数据文档,将稳定自动上传到网站分析系统指定的 FTP 服务器,网站分析系统从 FTP 服务器采集数据,通过验证后处理数据。”
其中的“稳定”应该改为“文档”,即将文档自动上传到网站分析系统指定的 FTP 服务器。
31. P418 计算整体波动量逻辑有误及对应图表错误(2018.11 更已修正)
在 P418 中,求相对昨天的环比变化率的计算方法为 (今日 - 昨日) / 今日,该逻辑应改为 (今日 - 昨日) / 昨日,对应到代码中:
python
这段应改为:
python
对应到 P419 中的输出结果应该为:
code
P415 的图 7-17 应该为:

P427 的图 7-19 应该为:

32. P83 通过 df.null 描述有误(2018.11 更已修正)
本页中,在代码下面有一段如下的描述:
“第三部分通过
df.null()方法找到所有数据框中的缺失值(默认缺失值是 NaN 格式),然后使用any()或all()方法来查找含有至少 1 个或全部缺失值的列”
其中的 df.null 应该为 df.isnull。
33. P101 “需要”描述有误(2018.11 更已修正)
本页中,有一段如下的描述:
“使用这种方法时需要对样本本身做额外处理,只需在算法模型的参数中进行相应设置即可。很多模型和算法中都有基于类别参数的调整设置”
其中的“需要”应该为“不需要”。
34. P112 “实施”计算的引擎描述有误(2018.11 更已修正)
本页中,有一段如下的描述:
“以上的数据记录数不是固定的,笔者在实际工作时,如果没有特定时间要求,一般都会选择一个适中的样本量做分析,此时会综合考虑特征数、特征值域分布数、模型算法适应性、建模需求等;而如果是面向机器计算的工作项目时,一般都会选择尽量多的数据参与计算,而有关算法实时性和效率的问题会让技术和运维人员配合实现,例如提高服务器配置、扩大分布式集群规模、优化底层程序代码、使用实施计算的引擎和机制等。”
其中的“实施”应该为“实时”。
35. P169 “atplotlib”拼写有误(2018.11 更已修正)
本页中,有一段如下的描述:
“第五部分模型效果可视化。先通过 K 均值模型对象的
cluster_centers_方法获得类别中心点;然后定义一个颜色集用来显示不同类别样本的颜色;通过 Matplotlib 的figure方法建立一块画布,再通过 for 循环读出每个类别,使用 numpy 的where方法得到不同分类下的数据集索引并建立各聚类数据子集,最后使用 atplotlib 的scatter方法和plot方法做散点图展示聚类子集内的样本点以及中心,如图 4-3。”
其中的 atplotlib 应该为 matplotlib。
36. P295 第五章的结论有误(2018.11 更已修正)
在本页中,在“基于 RFM 得分业务方得到这样的结论:”一段中有如下描述:
- 本周表现处于一般水平以上的用户的比例(R、F、M 三个维度得分均在 3 以上的用户数)相对上周环比增长了 1.3%。这种良好趋势体现了活跃度的提升。
- 本周低价值(R、F、M 得分为 111 以上)用户名单中,新增了 1221 个新用户,这些新用户的列表已经被取出。
这两段的描述中,由于 RFM 本身是基于相对区间划分的,在不同时间内的数据是不能直接用于对比的。例如:
- 上周的客户指标得分是 1/2/3/4/5,最后的 RFM 得分也是 1/2/3/4/5;
- 而如果本周的客户指标得分是 11/12/13/14/15,那么最后的 RFM 得分仍然是 1/2/3/4/5。
因此,这种基于相对区间的划分是“一次性”的,而不应该用于直接对比。如果要对比,可以使用绝对值的划分方法,即自定义区间划分方法。例如 <3 时得分为 1,3-5 得分为 2,5-8 得分为 3,以此类推。
37. P216 与 P217 中 print 字符串有误(2018.11 更已修正)
在 adf_val 中有如下代码:
python
在 acorr_val 中有如下代码:
python
这两段代码的标题应该互换。在 adf_val 中应该是:
python
在 acorr_val 中应该是:
python
38. P217 中 aic、bic 和 hqic 代码有误(2018.11 更已修正)
P217 中间靠下的代码框中:
python
应改为:
python
39. P32 提示中的 cvs 拼写错误(2018.11 更已修正)
本书的 P32 页提示中,有如下一段描述:
“提示:大多数情况下 txt(任意指定分隔符)、cvs(以逗号分隔的数据文件)、tsv(以 tab 制表符分隔的数据文件)是最常用的数据文件格式。当数据文件大小在百兆级别以下时,可以使用 Excel 等工具打开;数据文件大小在百兆级别时,推荐使用 Notepad 打开;当数据文件大小在 G 级别时,推荐使用 UltraEdit 打开。”
其中的“cvs”应该改为“csv”。
40. P196 关于提升度的计算结果有误
在左上角的关于提升度的计算中,其中有一段“在本示例中,Lift = (400) / (800) = 0.5”的描述。在这个例子中,准确的 Lift 应该是:
code
即,在购买了 A 的人中同时购买了 B 的比例(也就是置信度)除以购买 B 的比例,因此应该是:
code
41. P319 客单价公式名称有误
本页中,关于客单价的定义,书中写为:
每订单金额 = 订单金额 / 订单用户量
应该改为:
客单价 = 订单金额 / 订单用户量
42. 第三章 3.6 分层抽样的内层代码逻辑有问题
在本书第三章的 3.6 分层抽样过程中,sample_list(空列表)应该放在外层 for 循环里面,否则会导致抽样的 sample_list 中的结果会出现重复完整的值。
需要注意的是:由于原始文件的正样本为 58,因此抽样 200 个样本会导致错误。所以,需要调低 each_sample_count 的值,例如 50、30 或 20。
