[英]pyspark using one task for mapPartitions when converting rdd to dataframe
我很困惑为什么在将生成的RDD转换为rdd.mapPartitions
时,Spark正在为rdd.mapPartitions
使用1个任务。
这对我来说是一个问题,因为我想从:
DataFrame
- > RDD
- > rdd.mapPartitions
- > DataFrame
这样我就可以读取数据(DataFrame),将非SQL函数应用于数据块(RDD上的mapPartitions),然后转换回DataFrame,以便我可以使用DataFrame.write
进程。
我可以从DataFrame - > mapPartitions转到然后使用类似saveAsTextFile的RDD编写器,但这不太理想,因为DataFrame.write
进程可以执行覆盖和以Orc格式保存数据之类的操作。 所以我想了解为什么会这样,但从实际的角度来看,我主要关心的是能够从DataFrame - > mapParitions - >到使用DataFrame.write进程。
这是一个可重复的例子。 以下按预期工作, mapPartitions
有100个任务:
from pyspark.sql import SparkSession
import pandas as pd
spark = SparkSession \
.builder \
.master("yarn-client") \
.enableHiveSupport() \
.getOrCreate()
sc = spark.sparkContext
df = pd.DataFrame({'var1':range(100000),'var2': [x-1000 for x in range(100000)]})
spark_df = spark.createDataFrame(df).repartition(100)
def f(part):
return [(1,2)]
spark_df.rdd.mapPartitions(f).collect()
但是,如果最后一行改为spark_df.rdd.mapPartitions(f).toDF().show()
那么mapPartitions
只会有一个任务。
DataFrame.show()
仅显示数据帧的第一行数,默认情况下仅显示前20行。如果该数字小于每个分区的行数,则Spark是惰性的,仅评估单个分区,这相当于一项任务。
您还可以对数据帧进行collect
,计算和收集所有分区,并再次查看100个任务。
您仍将像以前一样首先看到runJob
任务,这是由toDF
调用引起的,以便能够确定结果数据帧的模式:它需要处理单个分区以便能够确定映射函数的输出类型。 在这个初始阶段之后,诸如collect
之类的实际行动将在所有分区上发生。 例如,对于我运行你的代码片段,最后一行替换为spark_df.rdd.mapPartitions(f).toDF().collect()
产生以下阶段:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.