Pyspark udf对于没有参数的函数失败,但是对于没有参数的lambda工作

时间:2019-04-23 22:07:56

标签: apache-spark pyspark apache-spark-sql user-defined-functions pyspark-sql

我正在尝试使用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

我已经设法实现了想要的行为,所以“解决方案”并不是我所要的(尽管我欢迎任何建议以更好或更惯用的方式来实现这种事情)。如果有人登陆这里寻找“方法”,请this other question might help

我真正想得到的是一个解释:为什么第一个解决方案失败并且第一个起作用?

我在Ubuntu 18.04.2上使用spark 2.4.0和python 3.7.3

1 个答案:

答案 0 :(得分:2)

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