創建 SparkSession
from pyspark.sql import SparkSession
spark = SparkSession.builder \
.appName("Word Count") \
.getOrCreate()
構建 sc
from pyspark.sql import SparkSession
spark = SparkSession.builder \
.appName("Word Count") \
.getOrCreate()
sc = spark.sparkContext
創建RDD
從內存生成創建
data = sc.parallelize([('a',1),('b',2),('c',3])])
- parallelize 的參數可以爲集合、元素list或dict。
讀文件創建
xs = sc.textFile('zx_xs_chapters.txt',2)
textFile
方法的最後一個參數代表數據集被劃分的分取的個數,如果創建時沒有指定可以通過下面方式重新分區:
xs = sc.textFile('zx_xs_chapters.txt')
xs = xs.repartition(2)
len(xs.glom().collect()) # Out: 2
這樣我們便讀進來一本小說的所有章節:
xs.take(1)
# Out: ['1#578c4a41a350f5245b52ef02#正文 第3章 拜師習武#黑漆漆的山崗上,蕭...有太極心法與震山掌做底子,勝天的刀法進步極快。#2#2017/12/5 ']
常用轉換
xs = xs.map(lambda row:row.split('#'))
xs
本身是一個類似於列表的RDD對象,包含若干元素。.map
方法接受一個函數,這個函數將會作用於xs
的每個元素,返回計算好的新的可迭代的RDD對象。
上面代碼中我們把小說每一章節內容按照#
分割,得到一個字段列表:
xs.take(1)
# Out:
[['1',
'578c4a41a350f5245b52ef02',
'正文 第3章 拜師習武',
'黑漆漆的山崗上,蕭勝天渾身...的刀法進步極快。',
'2',
'2017/12/5 ']]
對比沒有map
操作之前我們得到了一個分隔好的字段列表。
- 需要注意的是
xs.take(1)
僅僅取了我們RDD數據集
中的第一個元素,它是第一章的列表,包含若干字段。
我們再獲取前十章的標題看看:
title = xs.map(lambda list:list[2])
title.take(10)
# Out:
['正文 第3章 拜師習武',
'正文 第1章 霾氏部落',
'正文 第2章 祭靈',
'正文 第6章 戰利品',
'正文 第5章 挑釁!',
'正文 第3章 萬千世界',
'正文 第7章 陰謀',
'正文 第8章 入侵!',
'正文 第9章 激戰!',
'正文 第4章 滿載而歸']
除了map
之外還有一些很重要的轉換操作:
- filter 接受一個函數,對於返回值爲false的丟棄,主要功能是過濾。
- flatMap 與map類似,但它返回一個扁平的結果,它把每一行看做一個列表對待,然後將所有的記錄簡單地加入到一起。通過傳遞一個空列表可以丟棄格式不正確的記錄。
- distinct 去重
- sample 返回數據集的隨機樣本
- repartition 對數據集重新分區,如上文所示
在此不一一贅述
常用操作
和轉換不同,操作執行數據集上的計劃任務。一旦完成數據轉換,則可以執行相應轉換。
.take方法
如上文所示,這可以說是最有用的方法(也是用得最多的方法,如.map(…)方法)。該方法優於.collect(…),因爲它只返回單個數據分區的前n行,對比之下,.collect(…)返回的是整個RDD。
.collect方法
該方法將所有RDD的元素返回給驅動程序。
.reduce方法
reduce
方法接受一個函數,它把RDD的前兩個元素作爲參數傳入進行運算,運算結果再作爲一個元素和第三個元素傳入運算…,以此類推直至所有元素運算完畢,我們可以用這個操作計算小說正文部分的總字數:
len(xs.map(lambda list:list[3]).reduce(lambda x,y:x+y))
# Out: 844418
注意:
- reduce傳遞的函數需要是關聯的,即元素順序改變,結果不變;該函數還需要是交換的,即操作符順序改變,結果不變。
.count方法
統計RDD元素的數量:
xs.count()
# Out: 295
看來我們的小說一共有295章。
- 和
len(xs.collect())
不同的是該.count
方法不需要把整個數據集移動到驅動程序。
小結
我們瞭解瞭如何在Pyspark中創建和操作RDD,但Python RDD與Java、Scala相比速度慢很多。PySpark應用程序與Scala中編寫的數據結構相符的數據結構是DataFrame。