
Spark数据处理引擎是一个惊人的分析工厂:输入原始数据,输出洞察。PySpark用基于Python的API封装了Spark的核心引擎。它有助于简化Spark陡峭的学习曲线,并使这个强大的工具可供任何在Python数据生态系统中工作的人使用。
《Python和PySpark数据分析》帮助你使用PySpark解决数据科学的日常挑战。你将学习如何跨多台机器扩展处理能力,同时从任何来源(无论是Hadoop集群、云数据存储还是本地数据文件)获取数据。一旦掌握了基础知识,就可以通过构建机器学习管道,并配合Python、pandas和PySpark代码,探索PySpark的全面多功能特性。
主要内容
● 组织PySpark代码
● 管理任何规模的数据
● 充满信心地扩展你的数据项目
● 解决常见的数据管道问题
● 创建可靠的长时间运行的任务
关 于 本 书
本书将教你如何使用PySpark执行自己的大数据分析程序,以实际的场景讲授如何使用PySpark以及为什么使用PySpark。你将学习如何有效地采集和处理大规模数据,以及如何编写自己的数据转换程序。读完本书后,你应该能够熟练地使用PySpark编写自己的数据分析程序。
本书目标读者
本书使用由浅入深的用例展开,从简单的数据转换一直到机器学习管道。本书涵盖了数据分析的整个生命周期,从数据采集到结果使用,添加了更多关于数据源使用和转换的实用技术。
本书主要面向数据分析师、数据工程师和数据科学家,他们希望将Python代码扩展到更大的数据集。理想情况下,你应该在工作中或学习编程时编写过一些与数据相关的程序。如果已经熟练使用Python编程语言及其生态系统,你会从本书中学到更多的实用内容。
Spark(当然还有PySpark)从面向对象和函数式编程中借鉴了很多内容。我认为,仅仅为了有效地使用大数据,就要求完全掌握两种编程范式是不合理的。如果你理解Python类、装饰器和高级函数,就能熟练使用书中一些更高级的结构,让PySpark按照你的意愿运行。如果你对这些概念不熟悉,我会在本书(如果适用)正文和附录中讨论PySpark。
本书组织结构:路线图
本书分为3部分。第Ⅰ部分介绍PySpark及其计算模型。本部分还会介绍如何构建和提交一个简单的数据程序,重点介绍在每个PySpark程序中都会用到的核心操作,如数据帧中的数据选择、筛选、连接和分组。
第Ⅱ部分通过引入分层数据进一步深入介绍数据转换,分层数据是PySpark中可扩展数据程序的关键元素。我们还通过明智地引入SQL代码,探索弹性分布式数据集/用户自定义函数,在PySpark中高效地使用pandas及窗口函数,使程序更具表现力、更加灵活并具有更好的性能。我们还会探讨Spark的报表功能和资源管理,以找出潜在的性能问题。
最后,第III部分在第Ⅰ部分和第Ⅱ部分的基础上介绍了如何在PySpark中构建机器学习程序。在构建和评估机器学习管道之前,使用数据转换工具包创建和选择特征。最后,创建自己的机器学习管道组件,确保我们的机器学习程序具有最大的可用性和可读性。
本书的大部分章节都有练习。你应该能够用学到的知识回答这些问题。
我建议你从头到尾按顺序阅读本书,并根据需要使用附录。如果你想直接深入某个主题,我仍然建议你在深入某一章节之前先学习第Ⅰ部分。下面是一些硬依赖和软依赖,有助于你更高效地阅读本书。
● 第3章是第2章的直接延续。
● 第5章是第4章的直接延续。
● 第9章使用了第8章介绍的一些概念,但资深读者可以自己阅读。
● 第12章、第13章和第14章最好依次阅读。
关于代码
本书最适合使用Spark 3.1或Spark 3.2:Spark 3中引入了许多新功能,目前大多数商业版本都默认使用该版本。在适当的时候,我会为Spark 2.3/2.4提供向后兼容的指令。不推荐Spark 2.2或更低版本。我还推荐使用Python 3.6及以上版本(本书中我使用的是Python 3.8.8)。安装说明见附录B。
可以在https://github.com/jonesberg/DataAnalysisWithPythonAndPySpark上找到本书的配套代码库,其中包含数据和代码。有些部分还包含本书所开发程序的可运行版本,以及一些可选的练习。可扫描封底二维码下载本书源代码。
本书包含了许多源代码的示例,有带编号的代码清单,也有正常的文本。在这两种情况下,源代码的格式都是固定等宽字体,以将其与普通文本区分开。有时,代码也会以粗体字显示,以突出显示与本章前面步骤不同的代码,例如在现有代码中添加了新功能。
在许多情况下,原始源代码被重新格式化;添加了换行符,并修改了缩进,以方便排版和印刷。在极少数情况下,即使这样也不能满足排版需求,代码清单还会包括行连续标记(?)。此外,正文中源代码的注释通常会被删除。代码清单中大都包含注释,以突出重要的概念。
前 言
虽然计算机的功能越来越强大,能够处理更大的数据集,但我们对数据的需求增长得更快。因此,我们构建了新的工具,以便在多台计算机上扩展大数据任务。这是有代价的,早期的工具很复杂,不仅需要用户管理数据程序,还需要用户管理计算机集群本身的运行状况和性能。我记得我曾尝试扩展自己的程序,但却得到“只需要对数据集进行采样,然后继续工作”的建议。
PySpark改变了游戏规则。从流行的Python编程语言开始,它提供了一个清晰可读的API来操作非常大的数据集。尽管如此,当你坐下来编写代码时,就像在操作一台复杂且功能强大的机器。PySpark集功能强大、表现力强、用途广泛于一体。通过强大的多维数据模型,无论多大的数据规模,都可以通过清晰的路径构建数据程序,以实现可伸缩性。
作为一名构建信用风险模型的数据科学家,我深深喜欢上PySpark。在即将把模型迁移到新的大数据环境时,我们需要设计一个计划:在保持业务连续运行的同时智能地转换我们的数据产品。作为一个自封的Python人,我的任务是帮助团队熟悉PySpark并加速过渡。当我有机会在不同的用例上与无数客户合作时,我对PySpark的喜爱程度呈指数级增长。这些项目的共同点是什么?大数据和大问题都可以通过强大的数据模型解决。需要注意的是,大多数学习Spark的材料都是针对Scala和Java的,Python开发人员只能将代码转换成他们喜欢的编程语言。我写本书是为了将PySpark作为数据分析师的优秀工具进行推广。幸运的是,Spark项目真的让Python成为主要参与者。现在,你拥有了扩展数据程序的强大工具,这是史无前例的。
而一旦大数据被驯服,就可以发挥数据的无限可能。
目 录
第1章 介绍 1
1.1 什么是PySpark 1
1.1.1 从头开始:什么是Spark 2
1.1.2 PySpark = Spark + Python 3
1.1.3 为什么选择PySpark 3
1.2 PySpark的工作原理 5
1.2.1 使用集群管理器进行物理规划 6
1.2.2 懒惰的主管成就工厂的高效 8
1.3 你将从本书学到什么 11
1.4 我们将如何开始 12
1.5 本章小结 13
第Ⅰ部分 介绍:PySpark的第一步
第2章 使用PySpark编写的第一个数据处理程序 17
2.1 设置pyspark shell 18
2.1.1 SparkSession入口点 20
2.1.2 配置PySpark的日志级别 21
2.2 映射程序 22
2.3 采集和探索:为数据转换奠定基础 23
2.3.1 用spark.read将数据读入数据帧 24
2.3.2 从结构到内容:使用show()探索数据帧 27
2.4 简单的列转换:将句子拆解为单词列表 29
2.4.1 使用select()选择特定的列 30
2.4.2 转换列:将字符串拆分为单词列表 31
2.4.3 重命名列:alias和withColumnRenamed 33
2.4.4 重塑数据:将list分解成行 34
2.4.5 处理单词:更改大小写并删除标点符号 36
2.5 筛选记录 38
2.6 本章小结 40
2.7 扩展练习 40
第3章 提交并扩展你的第一个PySpark程序 43
3.1 对记录进行分组:计算词频 43
3.2 使用orderBy对结果排序 46
3.3 保存数据帧中的数据 48
3.4 整合所有内容:计数 49
3.4.1 使用PySpark的导入约定简化依赖 50
3.4.2 通过方法链简化程序 51
3.5 使用spark-submit以批处理模式启动程序 53
3.6 本章未涉及的内容 54
3.7 扩展词频程序 55
3.8 本章小结 56
3.9 扩展练习 57
第4章 使用pyspark.sql分析表格数据 59
4.1 什么是表格数据 60
4.2 使用PySpark分析和处理表格数据 62
4.3 在PySpark中读取和评估带分隔符的数据 63
4.3.1 第一次使用专门处理CSV文件的SparkReader 63
4.3.2 自定义SparkReader对象来读取CSV数据文件 65
4.3.3 探索数据世界的轮廓 67
4.4 数据操作基础:选择、删除、
重命名、排序及诊断 68
4.4.1 了解我们想要什么:选择列 69
4.4.2 只保留我们想要的:删除列 71
4.4.3 创建新列:使用withColumn()创建新列 73
4.4.4 整理数据帧:对列进行重命名和重排序 76
4.4.5 用describe()和summary()分析数据帧 78
4.5 本章小结 80
4.6 扩展练习 80
第5章 数据帧操作:连接和分组 83
5.1 连接数据 83
5.1.1 探索连接的世界 84
5.1.2 了解连接的两边 85
5.1.3 成功连接的规则:谓词 85
5.1.4 连接方法 87
5.1.5 连接的命名约定 91
5.2 通过groupby和GroupedData汇总数据 94
5.2.1 一个简单的分组蓝图 95
5.2.2 对自定义列使用agg() 98
5.3 处理null值:删除或填充 100
5.3.1 立即删除:使用dropna()
删除具有null值的记录 100
5.3.2 使用fillna()替换null值 101
5.4 问题回顾:端到端程序 102
5.5 本章小结 105
5.6 扩展练习 105
第Ⅱ部分 进级:将你的想法转化为代码
第6章 多维数据帧:使用PySpark处理JSON数据 109
6.1 读取JSON数据:为schemapocalypse做好准备 109
6.1.1 从小处开始:将JSON数据作为受限的Python字典 111
6.1.2 更进一步:在PySpark中读取JSON数据 113
6.2 用复杂的数据类型突破二维数据 114
6.2.1 当有多个值时:使用数组 116
6.2.2 映射类型:同一列中的键和值 119
6.3 结构体:列中的嵌套列 121
6.4 构建和使用数据帧模式 125
6.4.1 使用Spark类型作为schema的基本代码块 125
6.4.2 使用结构体模式原地读取JSON文档 127
6.4.3 循环往复:以JSON格式指定模式 131
6.5 进行整合:使用复杂数据类型减少重复数据 133
6.5.1 获取“刚刚好”的数据帧:explode和collect 135
6.5.2 创建自己的层次结构:作为函数的结构体 138
6.6 本章小结 139
6.7 扩展练习 139
第7章 双语PySpark:混合Python和SQL 141
7.1 根据我们的了解:pyspark.sql 与普通 SQL 142
7.2 为SQL准备数据帧 143
7.2.1 将数据帧转换为Spark表 144
7.2.2 使用Spark 145
7.3 SQL和PySpark 146
7.4 在数据帧方法中使用类似SQL的语法 148
7.4.1 获取所需的行和列:select和where 148
7.4.2 将相似的记录分组在一起:group by和order by 149
7.4.3 在分组后使用having进行筛选 150
7.4.4 使用CREATE关键字创建新表/视图 151
7.4.5 使用UNION和JOIN向表中添加数据 153
7.4.6 通过子查询和公共表表达式更好地组织SQL代码 154
7.4.7 PySpark与SQL语法的快速总结 157
7.5 简化代码:混合SQL和Python 157
7.5.1 使用Python提高弹性并简化数据读取阶段 158
7.5.2 在PySpark中使用SQL风格的表达式 159
7.6 结论 161
7.7 本章小结 161
7.8 扩展练习 162
第8章 使用Python扩展PySpark: RDD和UDF 165
8.1 PySpark中的RDD 166
8.2 使用Python通过UDF扩展PySpark 173
8.2.1 这一切都从简单的Python开始:使用类型化的Python函数 174
8.2.2 使用udf()将Python函数转换为UDF 176
8.3 本章小结 179
8.4 扩展练习 179
第9章 大数据就是大量的小数据:使用pandas UDF 181
9.1 通过pandas进行列转换:使用Series UDF 182
9.1.1 将Spark连接到谷歌的BigQuery 183
9.1.2 Series to Series UDF:使用pandas的列函数 188
9.1.3 标量UDF+冷启动=Series UDF的迭代器 190
9.2 分组数据上的UDF:聚合
与应用 193
9.2.1 分组聚合UDF 194
9.2.2 分组映射UDF 196
9.3 何时用,怎么用 198
9.4 本章小结 200
9.5 扩展练习 200
第10章 不同视角下的数据:窗口函数 203
10.1 学习并使用简单的窗口函数 204
10.1.1 确定每年最冷的一天 204
10.1.2 创建并使用一个简单的窗口函数来获取最冷的日子 206
10.1.3 比较两种方法 210
10.2 除了汇总:使用排名和分析功能 211
10.2.1 排名函数:看看谁是第一 212
10.2.2 分析函数:回顾过去和展望未来 216
10.3 弹性窗口!使用行和范围的边界 218
10.3.1 计数,窗口样式:静态、增长和无边界 219
10.3.2 范围和行 221
10.4 综合实践:在窗口中使用UDF 224
10.5 查看窗口:成功的窗口函数的主要步骤 226
10.6 本章小结 226
10.7 扩展练习 226
第11章 加速PySpark:理解Spark的查询计划 229
11.1 芝麻开门:通过Spark UI了解Spark环境 229
11.1.1 查看配置:Environment选项卡 231
11.1.2 Executors选项卡和resource management选项卡 233
11.1.3 了解任务的运行:通过Spark UI判断任务是否完成 237
11.1.4 通过Spark查询计划映射操作:SQL选项卡 240
11.1.5 Spark的核心:解析、分析、优化和物理计划 242
11.2 关于性能:操作和内存 246
11.2.1 宽操作与窄操作 246
11.2.2 缓存数据帧:功能强大,但往往致命(对于性能而言) 251
11.3 本章小结 254
第Ⅲ部分 使用PySpark进行机器学习
第12章 准备工作:为机器学习准备特征 259
12.1 阅读、探索和准备机器学习数据集 260
12.1.1 使用toDF()对列名进行标准化 261
12.1.2 探索数据并获取第一个特征列 262
12.1.3 解决数据错误并构建第一个特征集 264
12.1.4 删除无用记录并估算二分类特征 266
12.1.5 处理极值:清洗带有连续值的列 268
12.1.6 删除不常见的二分类列 271
12.2 特征创建和细化 272
12.2.1 创建自定义特征 272
12.2.2 去除高度相关的特征 273
12.3 基于转换器和估计器的特征准备 276
12.3.1 使用Imputer估计器填充连续特征 277
12.3.2 使用MinMaxScaler估计器对特征进行缩放 279
12.4 本章小结 281
第13章 通过机器学习管道增强机器学习 283
13.1 转换器和估计器: Spark
中机器学习的构建块 284
13.1.1 数据进出:转换器 285
13.1.2 估计器 289
13.2 构建(完整的)机器学习管道 290
13.2.1 使用向量列类型组装最终数据集 292
13.2.2 使用LogisticRegression分类器训练机器学习模型 295
13.3 评估和优化模型 297
13.3.1 评估模型准确率:混淆矩阵和评估器对象 298
13.3.2 真阳性与假阳性:ROC曲线 300
13.3.3 使用交叉验证优化超参数 302
13.4 从模型中获取最大的驱动力:提取系数 305
13.5 本章小结 307
第14章 构建自定义机器学习转换器和估计器 309
14.1 创建自己的转换器 309
14.1.1 设计转换器:从Param和转换的角度思考 310
14.1.2 创建转换器的Param 312
14.1.3 getter和setter:成为PySpark中优秀的一员 314
14.1.4 创建自定义转换器的初始化函数 316
14.1.5 创建转换函数 317
14.1.6 使用转换器 319
14.2 创建自己的估计器 321
14.2.1 设计估计器:从模型到Param 321
14.2.2 实现伴生模型:创建自己的Mixin 324
14.2.3 创建ExtremeValueCapper估计器 326
14.2.4 使用自定义估计器 328
14.3 在机器学习管道中使用转换器和估计器 328
14.3.1 处理多个输入 329
14.3.2 将自定义组件应用于机器学习管道 331
14.4 本章小结 334
14.5 结论:有数据,我就开心 334
附录A 习题答案 337
附录B 安装PySpark 369
附录C 一些有用的Python内容 389
《Python和PySpark数据分析》有 14 章和 3 个附录,详细介绍了如何将PySpark 应用到日常的数据科学工作中。通过通俗易懂的示例,介绍了PySpark中的实用知识点和语法,使你能够轻松掌握PySpark的核心概念,并将其应用于实际工作中。在本书中,你将学习如何使用 PySpark 进行数据预处理、模型训练和评估等常见的数据科学任务。每个章节都以具体的示例和案例展示了 PySpark 在不同情景下的应用方法和技巧。通过实际操作,你将了解如何使用 PySpark 处理大规模数据集、构建复杂的数据处理流程以及应对常见的数据质量和性能挑战。
作为一家数据驱动软件公司的ML总监,Jonathan Rioux每天都在使用PySpark。他向数据科学家、数据工程师和精通数据的业务分析师讲授PySpark的用法。