Pyspark udf не работает для функции без аргументов, но работает для лямбды без аргументов - PullRequest
1 голос
/ 24 апреля 2019

Я пытаюсь добавить столбец в мой Spark DataFrame, используя withColumn и udf без аргументов. Кажется, это работает, только если я использую лямбду для инкапсуляции своей исходной функции.

Вот 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

Мне удалось добиться желаемого поведения, поэтому «решение» - это не совсем то, что я ищу (хотя я и приветствую любые предложения о лучшем / более идиоматичном способе реализации такого рода вещей). Если кто-то приземлится в поисках ответа «как это сделать», этот другой вопрос может помочь .

Что мне действительно нужно, так это объяснение: почему первое решение терпит неудачу, а первое работает?

Я использую spark 2.4.0 и python 3.7.3 в Ubuntu 18.04.2

1 Ответ

2 голосов
/ 24 апреля 2019

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'))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...