Spark SQL .withColumn() 与列表达式

Spark SQL .withColumn() vs Column expressions

我想知道在pyspark中使用中间steps/columns时是否有任何performance/scalability区别:

  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()

问题:如果需要许多中间steps/columns,例如bar,这两个选项在space/time复杂度上是否不同?

我看到我原来的post被删除了。事后看来,除非缺乏沟通,否则这很可能是正确的。该示例使用的是 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