Pyspark:在UDF中传递多个列以及一个参数

时间:2018-10-16 20:20:22

标签: python pyspark user-defined-functions

我正在编写一个udf,它将使用两个数据框列以及一个额外的参数(一个常量值),并且应该向该数据框添加一个新列。我的功能如下:

def udf_test(column1, column2, constant_var):
    if column1 == column2:
        return column1
    else:
        return constant_var

此外,我正在执行以下操作以传递多列:

apply_test = udf(udf_test, StringType())
df = df.withColumn('new_column', apply_test('column1', 'column2'))

除非我将constant_var删除为函数的第三个参数,否则此操作现在不起作用,但我确实需要它。因此,我尝试执行以下操作:

constant_var = 'TEST'
apply_test = udf(lambda x: udf_test(x, constant_var), StringType())
df = df.withColumn('new_column', apply_test(constant_var)(col('column1', 'column2')))

apply_test = udf(lambda x,y: udf_test(x, y, constant_var), StringType())

以上都不对我有用。我基于thisthis stackoverflow帖子获得了这些想法,我认为我的问题与两者之间的区别是显而易见的。任何帮助将不胜感激。

注意:我仅出于讨论目的而在此处简化了该功能,而实际功能更为复杂。我知道可以使用whenotherwise语句完成此操作。

1 个答案:

答案 0 :(得分:4)

您不必使用用户定义的功能。您可以使用功能when()otherwise()

from pyspark.sql import functions as f
df = df.withColumn('new_column', 
                   f.when(f.col('col1') == f.col('col2'), f.col('col1'))
                    .otherwise('other_value'))

另一种实现方法是生成用户定义的函数。但是,使用udf对性能有负面影响,因为必须在python之间对数据进行反序列化。要生成用户定义的函数,您需要一个返回(用户定义的)函数的函数。例如:

def generate_udf(constant_var):
    def test(col1, col2):
        if col1 == col2:
            return col1
        else:
            return constant_var
    return f.udf(test, StringType())

df = df.withColumn('new_column', 
                   generate_udf('default_value')(f.col('col1'), f.col('col2')))