Spark SQL .withColumn()与列表达式

时间:2019-07-13 16:58:32

标签: apache-spark pyspark apache-spark-sql pyspark-sql

我想知道在pyspark之间使用中间步骤/列时,在性能/可扩展性方面是否存在任何差异:

  1. 使用.withColumn()例如:
    df = df.withColumn('bar', df.foo + 1)
    df = df.withColumn('baz', df.bar + 2)

然后致电df.select('baz').collect()

  1. 将Spark列声​​明为Python变量:
    bar = df.foo + 1
    baz = bar + 2

然后打电话 df.select(baz.alias('baz')).collect()

问题:如果需要许多中间步骤/列,例如bar,那么这两个选项的时空复杂度会有所不同吗?

1 个答案:

答案 0 :(得分:0)

我看到我原来的帖子被删除了。事后看来,除非缺乏沟通,否则很可能是正确的。该示例使用的是foldLeft,这不是您的用例,它是数据管道的融合。

要回答您的问题,Catalyst融合了数据管道操作意味着这两种方式都不会出现性能问题,

df = spark.createDataFrame([(x,x) for x in range(7)], ['foo', 'bar',])
df = df.withColumn('bar', df.foo + 1) 
df = df.withColumn('baz', df.bar + 2)
df.select('baz').explain(extended=True)

== Physical Plan ==
*(1) Project [(foo#276L + 3) AS baz#283L]
+- *(1) Scan ExistingRDD[foo#276L,bar#277L]  

同样:

df = spark.createDataFrame([(x,x) for x in range(7)], ['foo', 'bar',])
bar = df.foo + 1 
baz = bar + 2
df.select(baz.alias('baz')).explain(extended=True)

== Physical Plan ==
*(1) Project [(foo#288L + 3) AS baz#292L]
+- *(1) Scan ExistingRDD[foo#288L,bar#289L]

它们看起来与我非常相似...请注意+3的优化。

此外,我提醒您注意将foldLeft与.withColumn https://manuzhang.github.io/2018/07/11/spark-catalyst-cost.html

一起使用