spark - 将数据框转换为列表以提高性能

Posted

技术标签:

【中文标题】spark - 将数据框转换为列表以提高性能【英文标题】:spark - Converting dataframe to list improving performance 【发布时间】:2016-02-12 13:43:19 【问题描述】:

我需要将 Spark 数据框的一列转换为以后用于 matplotlib 的列表

df.toPandas()[col_name].values.tolist()

看起来这个操作需要大约 18 秒的高性能开销 还有其他方法可以做到这一点或提高性能吗?

【问题讨论】:

我猜性能开销是在 toPandas() 中,因为这是链中的第一个操作。 @JiriS 我能做些什么呢? 那一列有多少数据? Spark 必须将这一列的所有数据发送给驱动程序(加上序列化/反序列化开销)。你在使用 kryo 序列化吗?如果不启用它。 【参考方案1】:

你可以这样做:

>>> [list(row) for row in df.collect()]

示例:>>> d = [['Alice', 1], ['Bob', 2]]>>> df = spark.createDataFrame(d, ['name', 'age'])>>> df.show()+-----+---+| name|age|+-----+---+|Alice| 1|| Bob| 2|+-----+---+>>> to_list = [list(row) for row in df.collect()]print list 结果:[[u'Alice', 1], [u'Bob', 2]]

【讨论】:

虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。请阅读此how-to-answer 以提供高质量的答案。 根据@Artem Osipov 的回答,您可以使用 df.toLocalIterator() 而不是 df.collect() 以获得卓越的性能【参考方案2】:

如果你真的需要一个本地列表,你可以在这里做的不多,但一个改进是只收集一个列而不是整个DataFrame

df.select(col_name).flatMap(lambda x: x).collect()

【讨论】:

它并没有真正帮助我。也许可以做其他事情? 除了放弃整个想法?并不真地。为什么要本地列表? 对于matplotlib也许还有其他方法 好吧,对于初学者,您可以仔细检查您的管道。有没有理由期待更快的执行?你缓存重用的数据吗?除此之外,考虑使用不需要完整数据的更智能的可视化技术(采样、分桶、不同的外推方法、阴影)。您现在收集了多少数据? 几个月后你回答了这个问题,指出数据框不再支持 flatMap ***.com/a/37225736/1335793【参考方案3】:

您可以使用迭代器来节省内存toLocalIterator。迭代器将消耗与其中最大分区一样多的内存。如果你只需要使用一次结果,那么迭代器就是完美的这种情况。

d = [['Bender', 12], ['Flex', 123],['Fry', 1234]]
df = spark.createDataFrame(d, ['name', 'value'])
df.show()
+------+-----+
|  name|value|
+------+-----+
|Bender|   12|
|  Flex|  123|
|   Fry| 1234|
+------+-----+`
values = [row.value for row in df.toLocalIterator()]

print(values)
>>> [12, 123, 1234]

toPandas() 方法也应该只在预期结果 Pandas 的 DataFrame 很小的情况下使用,因为所有数据都加载到驱动程序的内存中。

【讨论】:

以上是关于spark - 将数据框转换为列表以提高性能的主要内容,如果未能解决你的问题,请参考以下文章

如何提高熊猫数据框的列表理解速度

如何提高以同步方式处理多个 Arraylist 请求的性能,以将它们创建为没有重复的最终列表

Parquet + Spark SQL

将文件列表 (JSON) 转换为数据框

将列表的列转换为数据框

提高 Spark.SQL 中的数据整理性能