Pandas vs Spark:數(shù)據(jù)讀取篇
導(dǎo)讀
按照前文所述,本篇開始Pandas和Spark常用數(shù)據(jù)處理方法對(duì)比系列。數(shù)據(jù)處理的第一個(gè)環(huán)節(jié)當(dāng)然是數(shù)據(jù)讀取,所以本文就圍繞兩個(gè)框架常用的數(shù)據(jù)讀取方法做以介紹和對(duì)比。

數(shù)據(jù)讀取是所有數(shù)據(jù)處理分析的第一步,而Pandas和Spark作為常用的計(jì)算框架,都對(duì)常用的數(shù)據(jù)源讀取內(nèi)置了相應(yīng)接口。總體而言,數(shù)據(jù)讀取可分為從文件讀取和從數(shù)據(jù)庫讀取兩大類,其中數(shù)據(jù)庫讀取包含了主流的數(shù)據(jù)庫,從文件讀取又區(qū)分為不同的文件類型?;诖?,本文首先分別介紹Pandas和Spark常用的數(shù)據(jù)讀取API,而后進(jìn)行簡(jiǎn)要對(duì)比分析。

過濾pandas中以read開頭的方法名稱
read_sql:用于從關(guān)系型數(shù)據(jù)庫中讀取數(shù)據(jù),涵蓋了主流的常用數(shù)據(jù)庫支持,一般來講pd.read_sql的第一個(gè)參數(shù)是SQL查詢語句,第二個(gè)參數(shù)是數(shù)據(jù)庫連接驅(qū)動(dòng),所以從這個(gè)角度講read_sql相當(dāng)于對(duì)各種數(shù)據(jù)庫讀取方法的二次包裝和集成;
read_csv:其使用頻率不亞于read_sql,而且有時(shí)考慮數(shù)據(jù)讀取效率問題甚至常常會(huì)首先將數(shù)據(jù)從數(shù)據(jù)庫中轉(zhuǎn)儲(chǔ)為csv文件,而后再用read_csv獲取。這一轉(zhuǎn)儲(chǔ)的過程目的有二:一是提高讀取速度,二是降低數(shù)據(jù)讀取過程中的運(yùn)行內(nèi)存占用(實(shí)測(cè)同樣的數(shù)據(jù)轉(zhuǎn)儲(chǔ)為csv文件后再讀取,內(nèi)存占用會(huì)更低一些);
read_excel:其實(shí)也是對(duì)xlrd庫的二次封裝,用來讀取Excel文件會(huì)更加方便,但日常使用不多;
read_json:json文件本質(zhì)上也屬于結(jié)構(gòu)化數(shù)據(jù),所以也可將其讀取為DataFrame類型,但如果嵌套層級(jí)差別較大的話,讀取起來不是很合適;
read_html:這應(yīng)該算是Pandas提供的一個(gè)小彩蛋了,表面上看它就是一個(gè)用于讀取html文件中數(shù)據(jù)表格的接口,但實(shí)際上有人卻拿他來干著爬蟲的事情……
read_clipboard:這可以算是Pandas提供的另一個(gè)小彩蛋,用于從剪切板中讀取結(jié)構(gòu)化數(shù)據(jù)到DataFrame中。至于數(shù)據(jù)是如何到剪切板中的,那方式可能就多種多樣了,比如從數(shù)據(jù)庫中復(fù)制、從excel或者csv文件中復(fù)制,進(jìn)而可以方便的用于讀取小型的結(jié)構(gòu)化數(shù)據(jù),而不用大費(fèi)周章的連接數(shù)據(jù)庫或者找到文件路徑!
read_table:可用于讀取txt文件,使用頻率不高;
read_parquet:Parquet是大數(shù)據(jù)中的標(biāo)志性文件,Pandas也對(duì)其予以支持,但依賴還是很復(fù)雜的;
另外,還有ocr和pickle等文件類型,其中OCR是Hive中的標(biāo)準(zhǔn)數(shù)據(jù)文件類型,與Parquet類似,也是列式存儲(chǔ),雖然Pandas也提供支持,但既然是大數(shù)據(jù),其實(shí)與Pandas已經(jīng)關(guān)系不大了;而pickle則是python中常用的序列化存儲(chǔ)格式。
在以上方法中,重點(diǎn)掌握和極為常用的數(shù)據(jù)讀取方法當(dāng)屬read_sql和read_csv兩種,尤其是read_csv不僅效率高,而且支持非常豐富的參數(shù)設(shè)置,例如支持跳過指定行數(shù)(skip_rows)后讀取一定行數(shù)(nrows)的數(shù)據(jù),就是這個(gè)小技巧使得曾經(jīng)小內(nèi)存的我也能得以處理大數(shù)據(jù),著實(shí)欣喜!

通過spark-shell的tab鍵補(bǔ)全得到spark.read.的系列方法
可以明顯注意到Spark的數(shù)據(jù)讀取API與Pandas接口名稱的一個(gè)顯著區(qū)別是:Spark采用二級(jí)接口的方式,即首先調(diào)用read屬性獲取讀接口的類,然后再區(qū)分?jǐn)?shù)據(jù)源細(xì)分為各種類型;而Pandas則是直接提供了read_各數(shù)據(jù)類型的API。仍然按照使用頻率來分:
spark.read.parquet:前面已經(jīng)提到,parquet是大數(shù)據(jù)中的標(biāo)準(zhǔn)文件存儲(chǔ)格式,也是Apache的頂級(jí)項(xiàng)目,相較于OCR而言,Parquet更為流行和通用。Parquet的優(yōu)勢(shì)也不少,包括內(nèi)置了數(shù)據(jù)Schema、高效的壓縮存儲(chǔ)等;
spark.read.jdbc:通過jdbc提供了對(duì)讀取各主流數(shù)據(jù)庫的支持,由于其實(shí)際上也是一個(gè)類,所以相應(yīng)的參數(shù)設(shè)置都要依托option方法來進(jìn)行傳遞,最后通過執(zhí)行l(wèi)oad實(shí)現(xiàn)數(shù)據(jù)的讀取。但不得不說,spark內(nèi)置的一些默認(rèn)參數(shù)相較于Pandas而言合理性要差很多,例如fetchSize默認(rèn)為10,這對(duì)于大數(shù)據(jù)讀取而言簡(jiǎn)直是致命的打擊,誰用誰知道……
spark.read.csv:spark對(duì)于csv文件也給予了很好的支持,但參數(shù)配置相較于Pandas而言則要遜色很多
spark.read.textFile:典型的txt文件讀取方式,相信很多人的一個(gè)Spark項(xiàng)目word count大多是從讀取txt文件開始的吧,不過對(duì)于個(gè)人而言好像也僅僅是在寫word count時(shí)才用到了read.textFile。
其他也有read.json和read.orc等,但使用頻率不高。
如果說Pandas讀取數(shù)據(jù)庫是最為常用的方法,那么Spark其實(shí)最為常用的當(dāng)屬Parquet,畢竟Parquet文件與Spark等同為Apache頂級(jí)項(xiàng)目,而且更具大數(shù)據(jù)特色,稱得上是大數(shù)據(jù)文件存儲(chǔ)的業(yè)界規(guī)范!
整體來看,Pandas和Spark在數(shù)據(jù)讀取方面都提供了豐富的接口,支持的數(shù)據(jù)源類型也大體相當(dāng)。但對(duì)參數(shù)支持和易用性方面,Pandas對(duì)數(shù)據(jù)庫和csv文件相對(duì)更加友好,而Spark與Parquet文件格式則更為搭配。雖然同為數(shù)據(jù)計(jì)算框架,但Pandas是單機(jī)計(jì)算模式,而Spark則是分布式計(jì)算,所以不同的數(shù)據(jù)量級(jí)也自然決定了數(shù)據(jù)源的側(cè)重點(diǎn)不同,本無高下之分,只能說各有千秋。
最后,感謝清華大學(xué)出版社為本公眾號(hào)讀者贊助《Scala和Spark大數(shù)據(jù)分析 函數(shù)式編程、數(shù)據(jù)流和機(jī)器學(xué)習(xí)》一本,截止下周一(3月22日)早9點(diǎn),公眾號(hào)后臺(tái)查看分享最多的前3名讀者隨機(jī)指定一人。
推薦語:本書在簡(jiǎn)要介紹Scala語言理解“面向?qū)ο蟆焙汀昂瘮?shù)式編程”等理念的基礎(chǔ)上,重點(diǎn)圍繞Spark的核心抽象概念以及Spark SQL、Spark Streaming和Spark GraphX等組件來分析結(jié)構(gòu)化和非結(jié)構(gòu)化數(shù)據(jù),開發(fā)出具備可伸縮性和容錯(cuò)能力的流式應(yīng)用。通過本書,你將學(xué)會(huì)用Spark來快速完成大數(shù)據(jù)分析,對(duì)于學(xué)習(xí)Scala和Spark將會(huì)非常有幫助。

相關(guān)閱讀:
