繁体   English   中英

pyspark在将rdd转换为dataframe时使用mapPartitions的一个任务

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM