利用這本書,你將學習以下內(nèi)容:了解如何選擇Spark轉換實現(xiàn)優(yōu)化的解決方案。探索強大的轉換和歸約,包括reduceByKey()、combineByKey()和mapPartitions()。理解數(shù)據(jù)分區(qū)以實現(xiàn)優(yōu)化查詢。使用PySpark設計模式構建和應用模型。對圖數(shù)據(jù)應用motif查找算法。使用GraphFrames API分析圖數(shù)據(jù)。對臨床醫(yī)學和基因組數(shù)據(jù)應用PySpark算法。學習如何在ML算法中使用和應用特征工程。了解并使用實用的數(shù)據(jù)設計模式。
編輯推薦
Apache Spark不僅速度快,易于使用,還提供了豐富的分析能力和多語言支持,掌握這個集群計算框架的實用知識已經(jīng)成為數(shù)據(jù)工程師和數(shù)據(jù)科學家的必b備技能。利用這本實用指南,想要了解Spark的人能從中學習實用的PySpark算法和示例。
每一章中,本書作者會向你展示如何用一組Spark轉換和算法解決一個數(shù)據(jù)問題。你會了解如何應對涉及ETL、設計模式、機器學習算法、數(shù)據(jù)分區(qū)和基因組分析的問題。每個技巧都提供了利用PySpark驅動器和shell腳本使用的PySpark算法。
專家推薦
如果你希望采用一種可伸縮的方式實現(xiàn)現(xiàn)有算法,或者正在使用Spark開發(fā)新的自定義算法,對于這些人,這本書是一個絕好的資源。
Matei Zaharia
斯坦福大學計算機科學副教授;
Databricks首席技術專家;
Apache Spark創(chuàng)始人
前言Spark 已經(jīng)成為大規(guī)模數(shù)據(jù)分析領域事實上的標準。自從幾年前Spark 誕生以來,我就一直在使用和教授Spark,在抽取、轉換、加載(ETL)過程、分布式算法開發(fā)以及大規(guī)模數(shù)據(jù)分析方面,Spark 都取得了長足的進步。我最初是用Java 使用Spark,但我發(fā)現(xiàn),雖然代碼相當穩(wěn)定,但寫的代碼行很長,這會讓代碼很難閱讀。在這本書中,我決定使用PySpark(Spark 的Python API),因為用Python 展現(xiàn)Spark 的強大功能更為容易:代碼簡短,易于閱讀,而且易于維護。PySpark 很強大,同時使用很簡單,利用PySpark 可以用一組簡單的轉換和動作實現(xiàn)任何ETL 或分布式算法。為什么寫這本書這是一本關于使用PySpark 實現(xiàn)數(shù)據(jù)分析的入門書。這本書提供了一組原則和示例,旨在幫助軟件和數(shù)據(jù)工程師用盡可能簡單的方式解決數(shù)據(jù)問題。我們知道,解決數(shù)據(jù)問題有很多方法:利用PySpark,我們能夠為復雜的問題編寫簡單的代碼。這正是我想通過本書表達的座右銘:保持簡單并使用參數(shù),使你的解決方案能夠被其他開發(fā)人員重用。我的目標是教讀者考慮數(shù)據(jù),了解其來源和最終的預期形式,并展示如何使用基本數(shù)據(jù)轉換模式解決各種數(shù)據(jù)問題。本書面向的讀者為了有效地使用這本書,了解Python 編程語言的基礎知識會很有幫助,例如如何使用條件語句(if-then-else)、迭代處理列表以及定義和調(diào)用函數(shù)。不過,如果你有其他編程語言背景(如Java 或Scala),還不了解Python,仍然可以使用這本書,因為我會提供Spark 和PySpark 的大量介紹。這本書主要面向那些想要分析大量數(shù)據(jù)并使用Spark 引擎和PySpark 開發(fā)分布式算法的人。我提供了一些簡單的示例,會展示如何用PySpark 完成ETL 操作和編寫分布式算法。我們采用了便于剪切粘貼的方式來編寫這些代碼示例,使你能輕松完成工作。GitHub(https://github.com/mahmoudparsian/dataalgorithms-with-spark)提供的示例代碼是一個很好的資源,可以由此起步著手完成你自己的數(shù)據(jù)項目。本書內(nèi)容組織本書共12 章,分為3 部分:第I 部分,基礎知識。前4 章涵蓋Spark 和PySpark 的基礎知識,并介紹數(shù)據(jù)轉換,如映射器、過濾器和歸約器。這幾章提供了很多實際示例,可以幫助你著手開發(fā)自己的PySpark 項目。約95% 的數(shù)據(jù)問題都可以通過使用本書前4 章介紹的簡單PySpark 數(shù)據(jù)轉換(如map()、flatMap()、filter() 和reduceByKey())來解決。下面詳細說明這幾章的內(nèi)容: 第1 章,Spark 和PySpark 簡介,提供了數(shù)據(jù)算法的高層概述,并介紹了如何使用Spark 和PySpark 解決數(shù)據(jù)分析問題。 第2 章,轉換實戰(zhàn),展示了如何使用Spark 轉換(映射器、過濾器和歸約器)解決實際數(shù)據(jù)問題。 第3 章, 映射器轉換, 介紹了最常用的映射器轉換:map()、filter()、flatMap() 和mapPartitions()。 第4 章,Spark 中的歸約,重點介紹歸約轉換(如reduceByKey()、groupByKey() 和combineByKey()),它們在按鍵分組數(shù)據(jù)時會發(fā)揮非常重要的作用。這一章給出了很多簡單但很有用的例子,確保你能有效地使用這些歸約。第II 部分,處理數(shù)據(jù)。接下來的4 章介紹數(shù)據(jù)分區(qū)、圖算法、讀/ 寫多個不同數(shù)據(jù)源的數(shù)據(jù),以及排名算法: 第5 章,數(shù)據(jù)分區(qū),介紹按特定數(shù)據(jù)列對數(shù)據(jù)物理分區(qū)的函數(shù)。通過這種分區(qū),SQL 查詢(例如,Amazon Athena 或Google BigQuery 中)能分析一個數(shù)據(jù)片而不是整個數(shù)據(jù)集,這將提高查詢性能。 第6 章,圖算法,會介紹最重要的Spark 外部包之一:GraphFrames,可以在Spark 分布式環(huán)境中用來分析大型圖。 第7 章,與外部數(shù)據(jù)源交互,會展示如何從各種不同數(shù)據(jù)源讀寫數(shù)據(jù)。 第8 章,排名算法,介紹了兩種重要的排名算法,PageRank(用于搜索引擎)和秩序乘積(用于基因分析)。第III 部分,數(shù)據(jù)設計模式。最后4 章介紹實用的數(shù)據(jù)設計模式,我們會通過具體的例子采用一種非正式的方式展示這些設計模式: 第9 章,經(jīng)典數(shù)據(jù)設計模式,將介紹常用于解決各種數(shù)據(jù)問題的一些基本數(shù)據(jù)設計模式或可重用的解決方案。例如輸入- 映射- 輸出和輸入-過濾- 輸出。 第10 章,實用數(shù)據(jù)設計模式,介紹了常見的實用數(shù)據(jù)設計模式,用于完成組合、匯總、過濾和組織數(shù)據(jù)等任務。我們會以非正式的方式介紹這些模式,并提供實際示例。 第11 章,連接設計模式,介紹連接兩個或多個數(shù)據(jù)集的簡單模式;為了提高連接算法的效率,這一章還會討論一些性能準則。 第12 章,PySpark 中的特征工程,介紹了開發(fā)機器學習算法中使用的最常見的特征工程技術。額外章節(jié)因為我不希望這本書過于龐大,本書的GitHub 存儲庫(https://github.com/mahmoudparsian/dataalgorithms-with-spark)中還提供了額外章節(jié),介紹關于TF-IDF、相關性和k-mers 等主題的附加內(nèi)容。排版約定本書采用以下排版約定。斜體(Italic)表示新術語、URL、電子郵件地址、文件名和文件擴展名。等寬字體(Constant Width)表示程序清單,在段落內(nèi)表示程序元素,例如變量、函數(shù)名稱、數(shù)據(jù)庫、數(shù)據(jù)類型、環(huán)境變量、語句和關鍵字。粗體等寬字體(Constant width bold)表示應由用戶原封不動輸入的命令或其他文本。斜體等寬字體(Constant width italic)表示應該替換成用戶提供值的文本,或者由上下文決定的值。使用代碼示例這本書的補充材料( 代碼示例、練習等) 可以從https://github.com/mahmoudparsian/data-algorithms-with-spark 下載。如果使用代碼示例時有技術問題或遇到其他問題,請通過以下email 聯(lián)系我們:mahmoud.parsian@yahoo.com。這本書的目的就是要幫助你完成工作。一般來講,你可以在你的程序和文檔中使用這些代碼,不需要聯(lián)系我們來得到許可,除非你直接復制了大部分的代碼。例如,如果你在編寫一個程序,使用了本書中的多段代碼,這并不需要得到許可。但是出售或發(fā)行OReilly 書示例代碼則需要得到許可。回答問題時如果引用了這本書的文字和示例代碼,這不需要得到許可。但是如果你的產(chǎn)品的文檔借用了本書中的大量示例代碼,則需要得到許可。我們希望但不嚴格要求標明引用出處。引用信息通常包括書名、作者、出版商和ISBN。例如Data Algorithms with Spark by Mahmoud Parsian (OReilly).Copyright 2022 Mahmoud Parsian, 978-1-492-08238-5。如果你認為你在使用代碼示例時超出了合理使用范圍或者上述許可范圍,可以隨時聯(lián)系我們:permissions@oreilly.com。OReilly 在線學習平臺(OReilly Online Learning)近40 年來,OReilly Media 致力于提供技術和商業(yè)培訓、知識和卓越見解,來幫助眾多公司取得成功。公司獨有的專家和改革創(chuàng)新者網(wǎng)絡通過OReilly 書籍、文章以及在線學習平臺,分享他們的專業(yè)知識和實踐經(jīng)驗。OReilly 在線學習平臺按照您的需要提供實時培訓課程、深入學習渠道、交互式編程環(huán)境以及來自OReilly 和其他200 多家出版商的大量書籍與視頻資料。更多信息,請訪問網(wǎng)站:https://www.oreilly.com/。聯(lián)系我們?nèi)魏斡嘘P本書的意見或疑問,請按照以下地址聯(lián)系出版社。美國:OReilly Media, Inc.1005 Gravenstein Highway NorthSebastopol, CA 95472中國:北京市西城區(qū)西直門南大街2 號成銘大廈C 座807 室(100035)奧萊利技術咨詢(北京)有限公司針對這本書,我們還建有一個網(wǎng)頁,列出了有關勘誤、示例和其他信息?梢酝ㄟ^以下地址訪問這個頁面:https://oreil.ly/data-algorithms-with-spark。如果對這本書有什么意見,或者詢問技術上的問題,請發(fā)送電子郵件至errata@oreilly.com.cn。有關我們的圖書和課程,更多新聞和信息請訪問我們的網(wǎng)站:http://www.oreilly.com。我們的LinkedIn:https://linkedin.com/company/oreilly-media。我們的Twitter:http://twitter.com/oreillymedia。我們的YouTube:http://youtube.com/oreillymedia。致謝寫這本書的想法是Jess Haberman(OReilly Media 高級策劃編輯)提出來的。非常感謝她伸出援手。謝謝你,Jess !感謝Melissa Potter(OReilly Media 內(nèi)容開發(fā)編輯),她從這個項目之初就不知疲倦地與我一同工作,她的幫助使這本書變得更好。非常感謝,Melissa !非常感謝文字編輯Rachel Head,她在整本書的編輯中做了大量工作。如果你能讀懂這本書,那都是Rachel 的功勞。我想對Christopher Faucher(產(chǎn)品編輯)衷心說聲謝謝,你出色的工作確保我們達成了最后期限,并且一切順利。一本書付梓出版絕不是一件容易的事情,但Christopher很出色地完成了這個工作。非常感謝技術審校Parviz Deyhim 和Benjamin Muskalla 對這本書細致的審查,以及后續(xù)的評論、更正和建議。還要特別感謝我的博士導師和親愛的朋友Ramachandran Krishnaswamy 博士,他讓我學到了很多東西;我會永遠珍惜與他的友誼。我在GitHub 上為所有章節(jié)提供了PySpark 解決方案,作為補充,Deepak Kumar和Biman Mandal 提供了Scala 解決方案,對讀者來說這是一個很好的資源。謝謝你們,Deepak 和Biman。最后(但絕不是不重要),非常感謝Matei Zaharia 博士(Apache Spark 創(chuàng)始人)為這本書寫了序,他的美言讓我倍感榮幸。
Mahmoud Parsian,計算機科學博士,作為開發(fā)人員、設計師、架構師和作者,他是一位有30多年豐富經(jīng)驗的軟件專業(yè)人士。在過去的15年里,他一直在從事Java服務器端計算、數(shù)據(jù)庫、MapReduce、Spark和分布式計算的相關工作。Parsian博士領導了Illumina的大數(shù)據(jù)團隊,專注于大規(guī);蚪M分析以及使用Spark和PySpark的分布式計算。Parsian博士還在圣克拉拉大學教授機器學習和大數(shù)據(jù)建模和分析課程。
目錄
序 1
前言 3
第I 部分 基礎知識
第1 章 Spark 和PySpark 簡介 13
1.1 為什么使用Spark 完成數(shù)據(jù)分析 14
1.1.1 Spark 生態(tài)系統(tǒng) 17
1.1.2 Spark 架構 18
1.2 PySpark 的能力 .25
1.3 Spark 數(shù)據(jù)抽象 30
1.3.1 RDD 示例 31
1.3.2 Spark RDD 操作 32
1.3.3 DataFrame 示例 36
1.4 使用PySpark Shell 38
1.4.1 啟動PySpark Shell .40
1.4.2 由集合創(chuàng)建RDD .41
1.4.3 聚合和合并鍵的值 .41
1.4.4 過濾RDD 的元素 43
1.4.5 對類似的鍵分組 44
1.4.6 聚合類似鍵的值 45
1.5 使用DataFrame 的ETL 示例 .46
1.5.1 抽取 47
1.5.2 轉換 48
1.5.3 加載 49
1.6 小結 .50
第2 章 轉換實戰(zhàn) 51
2.1 DNA 堿基計數(shù)示例 .52
2.1.1 DNA 堿基計數(shù)問題 55
2.1.2 FASTA 格式 55
2.1.3 示例數(shù)據(jù) .56
2.2 DNA 堿基計數(shù)解決方案1 56
2.2.1 步驟1:由輸入創(chuàng)建一個RDD[String] 57
2.2.2 步驟2:定義一個映射器函數(shù)59
2.2.3 步驟3:得出DNA 字母頻度 62
2.2.4 解決方案1 的優(yōu)缺點.64
2.3 DNA 堿基計數(shù)解決方案2 65
2.3.1 步驟1:由輸入創(chuàng)建一個RDD[String] 67
2.3.2 步驟2:定義一個映射器函數(shù)67
2.3.3 步驟3:得出DNA 字母頻度 69
2.3.4 解決方案2 的優(yōu)缺點.70
2.4 DNA 堿基計數(shù)解決方案3 71
2.4.1 mapPartitions() 轉換 71
2.4.2 步驟1:由輸入創(chuàng)建一個RDD[String] 79
2.4.3 步驟2:定義函數(shù)處理一個分區(qū) .79
2.4.4 步驟3:對各個分區(qū)應用自定義函數(shù) 82
2.4.5 解決方案3 的優(yōu)缺點.84
2.5 小結 .84
第3 章 映射器轉換 87
3.1 數(shù)據(jù)抽象和映射器 87
3.2 轉換是什么? .89
3.2.1 懶轉換 94
3.2.2 map() 轉換 96
3.2.3 DataFrame 映射器 102
3.3 flatMap() 轉換 .105
3.3.1 map() 與flatMap() 111
3.3.2 對DataFrame 應用flatMap() 111
3.4 mapValues() 轉換 115
3.5 flatMapValues() 轉換 116
3.6 mapPartitions() 轉換 . 118
3.6.1 處理空分區(qū) .121
3.6.2 優(yōu)缺點 125
3.6.3 DataFrame 和mapPartitions() 轉換 .126
3.7 小結 129
第4 章 Spark 中的歸約 131
4.1 創(chuàng)建(鍵,值)對RDD .132
4.2 歸約轉換.134
4.3 Spark 的歸約 136
4.4 簡單熱身示例 139
4.4.1 使用reduceByKey() 的解決方案 140
4.4.2 使用groupByKey() 的解決方案 141
4.4.3 使用aggregateByKey() 的解決方案 142
4.4.4 使用combineByKey() 的解決方案 143
4.5 什么是Monoid ? 144
4.6 電影問題.149
4.6.1 要分析的輸入數(shù)據(jù)集152
4.6.2 aggregateByKey() 轉換 .153
4.6.3 使用aggregateByKey() 的第一個解決方案 .154
4.6.4 使用aggregateByKey() 的第二個解決方案 .159
4.6.5 使用groupByKey() 的完整PySpark 解決方案 161
4.6.6 使用reduceByKey() 的完整PySpark 解決方案 164
4.6.7 使用combineByKey() 的完整PySpark 解決方案 167
4.7 歸約中的洗牌步驟 .170
4.7.1 groupByKey() 的洗牌步驟 172
4.7.2 reduceByKey() 的洗牌步驟 .173
4.8 小結 174
第II 部分 處理數(shù)據(jù)
第5 章 數(shù)據(jù)分區(qū) . 179
5.1 分區(qū)簡介.180
5.2 管理分區(qū).185
5.2.1 默認分區(qū) 186
5.2.2 顯式分區(qū) 187
5.3 為SQL 查詢完成物理分區(qū) 188
5.4 Spark 中的數(shù)據(jù)物理分區(qū) 192
5.4.1 分區(qū)為文本格式 192
5.4.2 分區(qū)為Parquet 格式 193
5.5 如何查詢分區(qū)數(shù)據(jù) .194
5.6 小結 196
第6 章 圖算法 . 199
6.1 圖介紹 .200
6.2 GraphFrames API 202
6.2.1 如何使用GraphFrames .203
6.2.2 GraphFrames 函數(shù)和屬性 .207
6.3 GraphFrames 算法 .207
6.3.1 查找三角形 .208
6.3.2 Motif 查找 212
6.4 實際示例.222
6.4.1 基因分析 223
6.4.2 社交推薦 224
6.4.3 Facebook 朋友圈 229
6.4.4 連通分量 234
6.4.5 分析航班數(shù)據(jù) .236
6.5 小結 246
第7 章 與外部數(shù)據(jù)源交互 247
7.1 關系數(shù)據(jù)庫 248
7.1.1 讀取數(shù)據(jù)庫 .249
7.1.2 將DataFrame 寫入數(shù)據(jù)庫 258
7.2 讀取文本文件 263
7.3 讀寫CSV 文件 265
7.3.1 讀CSV 文件 266
7.3.2 寫CSV 文件 270
7.4 讀寫JSON 文件 272
7.4.1 讀JSON 文件 .272
7.4.2 寫JSON 文件 .274
7.5 讀寫Amazon S3 .275
7.5.1 從Amazon S3 讀取 .277
7.5.2 寫入Amazon S3 278
7.6 讀寫Hadoop 文件 280
7.6.1 讀Hadoop 文本文件 281
7.6.2 寫Hadoop 文本文件 284
7.6.3 讀寫HDFS SequenceFile .287
7.7 讀寫Parquet 文件 288
7.7.1 寫Parquet 文件 .289
7.7.2 讀Parquet 文件 .291
7.8 讀寫Avro 文件 292
7.8.1 讀Avro 文件 292
7.8.2 寫Avro 文件 293
7.9 讀寫MS SQL Server .294
7.9.1 寫MS SQL Server 294
7.9.2 讀MS SQL Server 295
7.10 讀取圖像文件 295
7.11 小結 297
第8 章 排名算法 . 299
8.1 秩序乘積.300
8.1.1 計算秩序乘積 .301
8.1.2 秩序乘積描述 .301
8.1.3 秩序乘積示例 .302
8.1.4 PySpark 解決方案 304
8.2 PageRank 310
8.2.1 PageRank 的迭代計算 313
8.2.2 使用RDD 的自定義PySpark PageRank 算法實現(xiàn) 315
8.2.3 使用鄰接矩陣的自定義PySpark PageRank 算法實現(xiàn) 318
8.2.4 使用GraphFrames 實現(xiàn)的PageRank 321
8.3 小結 322
第III 部分 數(shù)據(jù)設計模式
第9 章 經(jīng)典數(shù)據(jù)設計模式 327
9.1 輸入?C 映射?C 輸出 .328
9.1.1 RDD 解決方案 329
9.1.2 DataFrame 解決方案 332
9.1.3 扁平映射器功能 334
9.2 輸入?C 過濾?C 輸出 .336
9.2.1 RDD 解決方案 337
9.2.2 DataFrame 解決方案 337
9.2.3 DataFrame 過濾器 338
9.3 輸入?C 映射?C 歸約?C 輸出 .340
9.3.1 RDD 解決方案 340
9.3.2 DataFrame 解決方案 344
9.4 輸入?C 多重?C 映射?C 歸約?C 輸出 346
9.4.1 RDD 解決方案 348
9.4.2 DataFrame 解決方案 350
9.5 輸入?C 映射?C 組合器?C 歸約?C 輸出351
9.6 輸入?C 映射分區(qū)?C 歸約?C 輸出 355
9.7 倒排索引.359
9.7.1 問題陳述 360
9.7.2 輸入 .360
9.7.3 輸出 .360
9.7.4 PySpark 解決方案 361
9.8 小結 364
第10 章 實用數(shù)據(jù)設計模式 367
10.1 映射器內(nèi)部組合 368
10.1.1 基本MapReduce 算法 .370
10.1.2 按記錄映射器內(nèi)部組合 372
10.1.3 按分區(qū)映射器內(nèi)部組合 374
10.2 Top-10 377
10.2.1 Top-N 形式化描述 .380
10.2.2 PySpark 解決方案 .381
10.2.3 查找Bottom 10384
10.3 MinMax 385
10.3.1 解決方案1:傳統(tǒng)MapReduce 385
10.3.2 解決方案2:排序 .386
10.3.3 解決方案 3:Spark 的mapPartitions() 386
10.4 復合模式和Monoid 390
10.4.1 Monoid 391
10.4.2 Monoid 和非Monoid 示例 395
10.4.3 非Monoid MapReduce 示例 .399
10.4.4 Monoid MapReduce 示例 401
10.4.5 Monoid 均值計算的PySpark 實現(xiàn) 403
10.4.6 函子和幺半群 406
10.4.7 幺半群使用小結 .408
10.5 分箱 408
10.6 排序 412
10.7 小結 413
第11 章 連接設計模式 . 415
11.1 連接操作介紹 415
11.2 MapReduce 中的連接 418
11.2.1 映射階段 419
11.2.2 歸約器階段 420
11.2.3 PySpark 實現(xiàn) 421
11.3 使用RDD 的映射端連接 .422
11.4 使用DataFrame 的映射端連接 .427
11.4.1 步驟1:創(chuàng)建Airports 緩存 429
11.4.2 步驟2:創(chuàng)建Airlines 緩存 429
11.4.3 步驟3:創(chuàng)建事實表 .430
11.4.4 步驟4:應用映射端連接 431
11.5 使用Bloom 過濾器的高效連接 431
11.5.1 Bloom 過濾器 432
11.5.2 一個簡單的Bloom 過濾器示例 434
11.5.3 Python 中的Bloom 過濾器 435
11.5.4 PySpark 中使用Bloom 過濾器 435
11.6 小結 436
第12 章 PySpark 中的特征工程 439
12.1 特征工程介紹 441
12.2 增加新特征 .443
12.3 應用UDF .444
12.4 創(chuàng)建管道 444
12.5 二值化數(shù)據(jù) .447
12.6 填充 449
12.7 分詞 451
12.7.1 Tokenizer 452
12.7.2 RegexTokenizer 453
12.7.3 管道分詞 453
12.8 標準化 454
12.9 歸一化 457
12.9.1 使用管道縮放一列 459
12.9.2 在多列上使用 MinMaxScaler 460
12.9.3 使用Normalizer 歸一化 .461
12.10 字符串索引 462
12.10.1 對單列應用StringIndexer463
12.10.2 對多列應用StringIndexer464
12.11 向量組合 464
12.12 分桶 .466
12.12.1 Bucketizer 467
12.12.2 QuantileDiscretizer .468
12.13 對數(shù)轉換 469
12.14 獨熱編碼 471
12.15 TF-IDF 477
12.16 FeatureHasher .482
12.17 SQLTransformer .483
12.18 小結 .484