當前位置: 首頁>>編程示例 >>用法及示例精選 >>正文


Python PySpark RDD map方法用法及代碼示例

PySpark RDD 的 map(~) 方法對 RDD 的每個元素應用一個函數。

參數

1. f | function

要應用的函數。

2. preservesPartitioning | boolean | optional

是否讓 Spark 假設分區仍然有效。這僅與 PairRDD 相關。請參閱下麵的示例以進行說明。默認情況下,preservesPartitioning=False

返回值

PySpark RDD (pyspark.rdd.PipelinedRDD)。

例子

將函數應用於 RDD 的每個元素

使 RDD 中的所有值都小寫:

# Create a RDD with 5 partitions
rdd = sc.parallelize(["A","B","C","D","E","F"], numSlices=5)
new_rdd = rdd.map(lambda x: x.lower())
new_rdd.collect()



['a', 'b', 'c', 'd', 'e', 'f']

將map方法應用於RDD時保留分區

preservesPartitioning 參數僅在 RDD 包含元組列表(成對 RDD)時起作用。

當 RDD 通過 partitionBy(~) (使用哈希分區器)重新分區時,我們保證具有相同鍵的元組最終位於同一分區中:

rdd = sc.parallelize([("A",1),("B",1),("C",1),("A",1),("D",1)], numSlices=3)
new_rdd = rdd.partitionBy(numPartitions=2)
new_rdd.glom().collect()



[[('C', 1)], [('A', 1), ('B', 1), ('A', 1), ('D', 1)]]

事實上,我們看到元組 ('A',1)('A',1) 位於同一分區中。

現在讓我們執行 map(~) 操作,並將 preservesPartitioning 設置為 False(默認):

mapped_rdd = new_rdd.map(lambda my_tuple: (my_tuple[0], my_tuple[1]+3))
mapped_rdd.glom().collect()



[[('C', 4)], [('A', 4), ('B', 4), ('A', 4), ('D', 4)]]

在這裏,我們應用map(~),它返回一個具有相同鍵但具有不同值的元組。我們可以看到分區沒有改變。然而,在幕後,Spark 內部有一個標誌來指示分區是否已被破壞,由於默認設置為 preservesPartitioning=False,因此該標誌現在已設置為 True(即分區已被破壞)。 Spark 這樣做是天真的,因為元組鍵沒有改變,所以分區應該仍然有效。

我們可以確認 Spark 現在天真地不知道數據是通過執行像 reduceByKey(~) 這樣的混洗操作來按元組鍵分區的:

mapped_rdd_reduced = mapped_rdd.reduceByKey(lambda x: x+y)
print(mapped_rdd_reduced.toDebugString().decode("utf-8"))



(2) PythonRDD[238] at RDD at PythonRDD.scala:58 []
 |  MapPartitionsRDD[237] at mapPartitions at PythonRDD.scala:183 []
 |  ShuffledRDD[236] at partitionBy at <unknown>:0 []
 +-(2) PairwiseRDD[235] at reduceByKey at <command-1339085475381822>:1 []
    |  PythonRDD[234] at reduceByKey at <command-1339085475381822>:1 []
    |  MapPartitionsRDD[223] at mapPartitions at PythonRDD.scala:183 []
    |  ShuffledRDD[222] at partitionBy at <unknown>:0 []
    +-(3) PairwiseRDD[221] at partitionBy at <command-1339085475381815>:2 []
       |  PythonRDD[220] at partitionBy at <command-1339085475381815>:2 []
       |  ParallelCollectionRDD[219] at readRDDFromInputStream at PythonRDD.scala:413 []

可以看到確實發生了洗牌。然而,這是完全沒有必要的,因為我們知道具有相同鍵的元組位於同一分區(機器)中,因此該操作可以在本地完成。

現在,考慮當我們將 preservesPartitioning 設置為 True 時的情況:

mapped_rdd_preserved = new_rdd.map(lambda my_tuple: (my_tuple[0], my_tuple[1]+3), preservesPartitioning=True)
mapped_rdd_preserved_reduced = mapped_rdd_preserved.reduceByKey(lambda x: x+y)
print(mapped_rdd_preserved_reduced.toDebugString().decode("utf-8"))



(2) PythonRDD[239] at RDD at PythonRDD.scala:58 []
 |  MapPartitionsRDD[223] at mapPartitions at PythonRDD.scala:183 []
 |  ShuffledRDD[222] at partitionBy at <unknown>:0 []
 +-(3) PairwiseRDD[221] at partitionBy at <command-1339085475381815>:2 []
    |  PythonRDD[220] at partitionBy at <command-1339085475381815>:2 []
    |  ParallelCollectionRDD[219] at readRDDFromInputStream at PythonRDD.scala:413 []

我們可以看到沒有發生洗牌。這是因為我們告訴 Spark 我們隻更改了元組的值,而不是鍵,因此 Spark 應該假設原始分區保持不變。

相關用法


注:本文由純淨天空篩選整理自Isshin Inada大神的英文原創作品 PySpark RDD | map method。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。