Передача константных значений в PySpark UDF

При работе с PySpark RDD передача константных значений в функцию довольно тривиальна, то с Dataframe все капельку сложнее.

Простые константы

Это числа, строки, туплы. Такие константы проще всего передавать через pyspark.sql.functions.lit. Это функция создает колонку из значения.

from pyspark.sql import functions as f
from pyspark.sql import types as t


@f.udf(t.IntegerType())
def foo_bar_udf(col, value):
    if col == 'foo':
        return value
    return 0

def main():
    df = df.withColumn('new_col', foo_bar_udf(f.col('col1'), f.lit(1)))

Комплексные константы

К сожалению, при передаче в функцию lit значений list, dict и тд, возникнет ошибка, что данные тип не поддерживается. Возможно, в версиях Spark выше 2.3 это уже возможно, но на сегодняшний день, чтобы обойти это, приходится городить лямбда-костыли.

def foo_bar(col, value):
    return value.get(col, 0)


def main():
    d = {'foo': 1, 'bar': 2}

    foo_bar_udf = f.udf(
        lambda col: foo_bar(col, d),
        t.IntegerType()
    )

    df = df.withColumn('new_col', foo_bar_udf(f.col('col1')))