Pyspark UDF应用于2列,返回1个新列

时间:2019-02-25 03:24:27

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

使用Pyspark 2.2

我有一个带有多个列的spark DataFrame。我需要向UDF输入2列并返回第3列

输入:

+-----+------+
|col_A| col_B|
+-----+------+
|  abc|abcdef|
|  abc|     a|
+-----+------+

col_Acol_B均为StringType()

所需的输出:

+-----+------+-------+
|col_A| col_B|new_col|
+-----+------+-------+
|  abc|abcdef|    abc|
|  abc|     a|      a|
+-----+------+-------+

我希望new_colcol_A的子串,长度为col_B

我尝试了

udf_substring = F.udf(lambda x: F.substring(x[0],0,F.length(x[1])), StringType())
df.withColumn('new_col', udf_substring([F.col('col_A'),F.col('col_B')])).show()

但是它给出了TypeError: Column is not iterable

有人知道如何进行这种操作吗?

1 个答案:

答案 0 :(得分:0)

这里有两个主要问题。

  • 首先,您将 NavigationService.navigate(action.payload); 定义为接受一个应为2的输入参数。
  • 第二,您不能在udf中使用API​​函数。 (调用udf会序列化为python,因此您需要使用python语法和函数。)

这是解决此问题的正确的udf实现:

udf

然后通过传入两列作为参数来调用它:

import pyspark.sql.functions as F

def my_substring(a, b):
    # You should add in your own error checking
    return a[:len(b)]

udf_substring = F.udf(lambda x, y: my_substring(a, b), StringType())

但是,在这种情况下,您可以使用this post中描述的方法在没有df.withColumn('new_col', udf_substring(F.col('col_A'),F.col('col_B'))) 的情况下执行此操作。

udf