繁体   English   中英

Spark dataFrame 更新其列后显示时间过长

[英]Spark dataFrame taking too long to display after updating its columns

我有一个大约的数据帧。 400 万行和 35 列作为输入。

我对这个数据框所做的只是以下步骤:

  • 对于给定列的列表,我计算给定组特征列表的总和,并将其作为新列加入到我的输入数据帧中
  • 在将每个新列和加入数据帧后,我立即删除它。

因此,我们最终得到与我们开始时相同的数据帧(理论上)。

但是,我注意到如果我的给定列列表变得太大(超过 6 列),则输出 dataFrame 变得无法操作。 即使是简单的显示也需要 10 分钟。

这是我的代码示例(df 是我的输入数据帧):

  for c in list_columns:
    df = df.join(df.groupby(list_group_features).agg(sum(c).alias('sum_' + c)), list_group_features)
    df = df.drop('sum_' + c)

这是由于 Spark 的内部工作原理及其惰性求值造成的。

当您调用groupbyjoinagg ,Spark 会做什么,它将这些调用附加到df对象的计划中。 因此,即使它没有对数据执行任何操作,您也正在创建一个内部存储在 Spark DataFrame 对象中的大型执行计划。

只有当你调用一个动作( showcountwrite等)时,Spark 才会优化计划并执行它。 如果计划太大,优化步骤可能需要一段时间才能执行。 还要记住,计划优化发生在驱动程序上,而不是执行程序上。 因此,如果您的驱动程序很忙或超载,它也会延迟火花计划优化步骤。

记住连接是 Spark 中的昂贵操作,无论是优化还是执行,这都是有用的。 如果可以,在单个 DataFrame 上操作时应始终避免连接,而应使用窗口功能。 仅当您连接来自不同来源(不同表)的不同数据框时,才应使用连接。

优化代码的一种方法是:

import pyspark
import pyspark.sql.functions as f

w = pyspark.sql.Window.partitionBy(list_group_features)
agg_sum_exprs = [f.sum(f.col(c)).alias("sum_" + c).over(w) for c in list_columns]
res_df = df.select(df.columns + agg_sum_exprs)

对于大型list_group_featureslist_columns列表,这应该是可扩展且快速的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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