Pyspark udf 对于没有参数的函数失败但适用于没有参数的 lambda

Pyspark udf fails for a function with no arguments but works for a lambda with no arguments

我正在尝试使用 withColumn 和不带参数的 udf 向我的 Spark DataFrame 添加一列。这似乎只有在我使用 lambda 封装我的原始函数时才有效。

这是一个 MWE:

from pyspark.sql import Row, SparkSession
from pyspark.sql.functions import udf

spark = SparkSession.builder.getOrCreate()
df = spark.createDataFrame([Row(number=i) for i in range(10)])

def foo():
    return 'bar'

udfoo = udf(foo())
df = df.withColumn('word', udfoo())
# Fails with TypeError: _create_udf() missing 1 required positional argument: 'f'

udfoo = udf(lambda: foo())
df = df.withColumn('word', udfoo())
# Works

我已经设法实现了我想要的行为,所以 "solution" 并不是我想要的(尽管我欢迎任何关于 better/more 惯用实现方式的建议这种事情)。如果有人登陆这里寻找 "how to do it" 答案,.

我真正想要的是解释:为什么第一个解决方案失败而第一个解决方案成功?

我在 Ubuntu 18.04.2

上使用 spark 2.4.0 和 python 3.7.3

udf 期望将一个函数传递给它,但是当您调用 foo() 时,它会立即计算为一个字符串。

如果使用 udf(foo) 而不是 udf(foo()),您将看到预期的行为。

udfoo = udf(foo)
df = df.withColumn('word', udfoo())

万一它有帮助,如果你正在试图获得一个只是常量值的列,你可以使用pyspark.sql.functions.lit,比如:

from pyspark.sql import functions as F

df.withColumn('word', F.lit('bar'))