【问题标题】:spark - Converting dataframe to list improving performancespark - 将数据框转换为列表以提高性能
【发布时间】:2023-04-08 22:38:01
【问题描述】:

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

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

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

【问题讨论】:

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

标签: python performance pandas apache-spark pyspark


【解决方案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 stackoverflow.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 很小的情况下使用,因为所有数据都加载到驱动程序的内存中。

【讨论】:

    猜你喜欢
    • 2017-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-17
    • 1970-01-01
    • 2021-08-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多