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'))
我正在尝试使用 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.3udf
期望将一个函数传递给它,但是当您调用 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'))