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 應該假設原始分區保持不變。
相關用法
- Python PySpark RDD zip方法用法及代碼示例
- Python PySpark RDD collect方法用法及代碼示例
- Python PySpark RDD repartition方法用法及代碼示例
- Python PySpark RDD countByKey方法用法及代碼示例
- Python PySpark RDD partitionBy方法用法及代碼示例
- Python PySpark RDD reduceByKey方法用法及代碼示例
- Python PySpark RDD coalesce方法用法及代碼示例
- Python PySpark RDD zipWithIndex方法用法及代碼示例
- Python PySpark RDD count方法用法及代碼示例
- Python PySpark RDD filter方法用法及代碼示例
- Python PySpark RDD collectAsMap方法用法及代碼示例
- Python PySpark RDD first方法用法及代碼示例
- Python PySpark RDD keys方法用法及代碼示例
- Python PySpark RDD glom方法用法及代碼示例
- Python PySpark RDD getNumPartitions方法用法及代碼示例
- Python Django Response.json用法及代碼示例
- Python Django Repeat用法及代碼示例
- Python Django RandomUUID用法及代碼示例
- Python Django RelatedManager.set用法及代碼示例
- Python RLock acquire()用法及代碼示例
- Python Django RelatedManager.remove用法及代碼示例
- Python Random.Choices()用法及代碼示例
- Python Django RequestContext用法及代碼示例
- Python Django Reverse用法及代碼示例
- Python NumPy Random Generator uniform方法用法及代碼示例
注:本文由純淨天空篩選整理自Isshin Inada大神的英文原創作品 PySpark RDD | map method。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。