- 更新時間:2018-10-16
RDD的內部運行方式
Spark優勢:每個轉換操作並行執行,大大提高速度。
數據集的轉換通常是惰性的,即在transformation過程不會執行程序,只有在action過程纔會執行。
創建RDD
導入相關程序庫
from pyspark import SparkContext as sc
from pyspark import SparkConf
創建RDD
# 將list或array轉爲RDD
data = sc.parallelize(
[("A", 2), ("B", 3), ("C", 4)])
# 從本地或外部文件導入
data_from_file = sc.textFile(path, n) # n爲分區
Schema
RDD是無Schema的數據結構,因此可以混合使用tuple、dict、list等多種數據結構。
全局作用域與局部作用域
Spark可以在兩種模式下運行:本地模式和集羣模式。
transformation操作
.map(…)
該方法應用在每一個RDD元素上,與python中的map
函數類似:
data_new = data.map(lambda row: (row,1))
.filter(…)
該方法對RDD中元素按照條件進行過濾:
data_filtered = data.filter(lambda row: row[1] == 2 or row[1] == 3)
.flatMap(…)
.flatMap(…)
方法和.map(...)
方法類似,但.flatMap(…)
方法返回一個扁平結果,而不是一個列表。
data_flat = data.flatMap(lambda row: row[1]+1)
.distinct(…)
該方法返回指定列中不同值的列表:
data_distinct = data.map(lambda row: (row,1)).distinct()
.sample(…)
該方法返回數據集的隨機樣本,第一個參數指定採樣是否應該替換,第二個參數定義返回數據的分數,第三個參數是僞隨機數產生器的種子。
fraction = 0.1
data_sample = data.sample(False, fraction, 666)
上例中,從原數據集中隨機抽樣10%。
.leftOuterJoin(…)
與SQL中left join
的語法類似,用以鏈接兩個RDD:
rdd1 = sc.parallelize([('a', 1), ('b', 4), ('c', 10)])
rdd2 = sc.parallelize([('a', 4), ('a', 1), ('b', '6'), ('d', 11)])
rdd3 = rdd1.leftOuterJoin(rdd2)
運行結果如下:
rdd3.collect()
# Out[1]: [('c',(10, None)), ('b', (4,'6')), ('a', (1,4)), ('a', (1,1))]
此外,還有.join(...)
和.intersection(...)
方法,均與SQL中意義相同。
.repartition(…)
該方法重新對數據集進行分區,改變數據集分區的數量:
rdd1 = rdd1.repartition(4)
上例中,將rdd1
重新設置了4個分區。
Action操作
.take(…)
該方法用於返回RDD中單個分區的前n行元素:
rdd1.take(1)
如果想要隨機的記錄,可以使用takeSample(...)
方法,這個方法有三個參數:第一個參數表示採樣是否應該被替換,第二個參數指定要返回的記錄數量,第三個參數是僞隨機數發生器種子。
data_take_sample = data.takeSample(False, 1, 667)
.collect(…)
與.take(...)
方法類似,但.collect(...)
方法返回全部RDD元素,因此在大規模RDD時不推薦使用。
.reduce(…)
.reduce(...)
方法使用指定的方法減少RDD中的元素。
rdd1.map(lambda row: row[1]).reduce(lambda x,y: x+y)
上述方法用於計算RDD總的元素數量,首先通過.map(...)
轉換,創建一個包含rdd1所有值的列表,然後使用.reduce(...)
方法對結果進行處理。
.reduceByKey(...)
方法和.reduce(...)
方法類似,但.reduceByKey(...)
是在鍵-鍵基礎上進行:
data_key = sc.parallelize([('a',4),('b',3),('c',2),('a',3),('d',2),('b',5),('d',1)], 4)
data_key.reduceByKey(lambda x, y: x + y).collect()
#Out[2]: [('b',8),('a',7),('c',2),('d',3)]
.count(…)
該方法用於統計RDD中元素數量,如果數據集是k-v格式的,可以使用countByKey(...)
獲取不同鍵的計數:
data.count()
data.countByKey().items()
.saveAsTextFile(…)
該方法將RDD保存爲文件,每個文件一個分區:
data.saveAsTextFile(path + filename)