Python 如何在大型Pyspark数据帧中遍历列的不同值。distinct().collect()引发一个大型任务警告

Python 如何在大型Pyspark数据帧中遍历列的不同值。distinct().collect()引发一个大型任务警告,python,pyspark,Python,Pyspark,我试图遍历大型Pyspark数据帧列中的所有不同值。当我尝试使用.distinct().collect()执行此操作时,即使只有两个不同的值,也会引发“任务太大”警告。 警告信息: 20/01/13 20:39:01 WARN TaskSetManager: Stage 0 contains a task of very large size (201 KB). The maximum recommended task size is 100 KB. 以下是一些示例代码: from pyspa

我试图遍历大型Pyspark数据帧列中的所有不同值。当我尝试使用
.distinct().collect()
执行此操作时,即使只有两个不同的值,也会引发“任务太大”警告。 警告信息:

20/01/13 20:39:01 WARN TaskSetManager: Stage 0 contains a task of very large size (201 KB). The maximum recommended task size is 100 KB.
以下是一些示例代码:

from pyspark.sql import SparkSession

spark = SparkSession.builder.appName('Basics').getOrCreate()
length = 200000

data = spark.createDataFrame([[float(0) for x in range(3)] for x in range(length)], ['a', 'b', 'c'])

data.select("a").distinct().collect()
# This code produces this warning

如何在大型Pyspark数据帧的列中迭代不同的值而不出现内存问题?

正如您所知,
.collect()
不是最佳做法。因为,这是一个将所有数据从执行者传输到驱动者的动作。问题是,当您有一个大数据集时,Spark执行器会向驱动程序发送大量序列化数据,然后收集这两行数据。您还可以查看生成警告的

从更高的层次上讲,解决问题的一个方法是用磁盘交换内存。您可以在一个csv中使用不同的值写入数据帧,然后用Python或Pandas*逐行读取数据帧:

data.select("a").distinct().coalesce(1).write.csv("temp.csv")
# Specifically, it's a directory with one csv.
使用此解决方案,您将不会有任何内存问题


*有很多关于如何使用Python或Pandas读取大型CSV的解决方案。

但是,既然只有两个不同的值,那么.collect()不应该工作吗?只有两个不同值的小型原始数据帧不会引发此警告。但是,当您有一个只有两个不同值的大型原始数据帧时,会抛出错误。为什么原始数据帧的大小很重要?正如您所看到的,警告消息来自TaskSetManager。如果我们在中的类中搜索,我们会在第448行中找到消息。正如您在if语句中看到的,您的任务超出了序列化内存限制。因为,当您有一个大数据集时,Spark执行器会向驱动程序发送大量数据,然后收集2个数据集rows@Jimmy我根据你的评论和我上面的评论编辑我的答案。现在清楚了吗?所以我尝试了这个解决方案,但没有任何帮助。当我运行此代码时,警告仍然存在。“data.select(“a”).distinct().coalesce(1).write”很好,但“.csv”(.temp.csv”)触发相同的警告。有什么想法吗?@ggeop您提到的代码负责任务大小而不是内存管理。方法
dequeueTask
负责任务的序列化和执行。如果您尝试运行
df.select(“*”)。limit(1)。collect()
?是的。我在运行该线路时收到相同的警告。