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 - 将数据框转换为列表以提高性能的主要内容,如果未能解决你的问题,请参考以下文章