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。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。