Pyspark 子字符串在 UDF 内部不起作用

Posted

技术标签:

【中文标题】Pyspark 子字符串在 UDF 内部不起作用【英文标题】:Pyspark substring is not working inside of UDF 【发布时间】:2020-02-06 15:12:21 【问题描述】:

我试图在 UDF 中使用 Pyspark 子字符串函数是徒劳的。下面是我的代码 sn-p -

from pyspark.sql.functions import substring

def my_udf(my_str):
    try:
        my_sub_str = substring(my_str,1, 2)
    except Exception:
        pass
    else:
        return (my_sub_str)

apply_my_udf = udf(my_udf)

df = input_data.withColumn("sub_str", apply_my_udf(input_data.col0))

样本数据是-

ABC1234
DEF2345
GHI3456

但是当我打印 df 时,我在新列“sub_str”中没有得到任何值,如下所示 -

[Row(col0='ABC1234', sub_str=None), Row(col0='DEF2345', sub_str=None), Row(col0='GHI3456', sub_str=None)]

谁能告诉我我做错了什么?

【问题讨论】:

这是因为you can not use any of the pyspark.sql.functions inside of a udf。你也不能reference a spark DataFrame inside a udf。因为你有一个naked except,所以你正在吞下真正的错误消息并返回None,因为这就是没有return时python函数所做的事情。 【参考方案1】:

您不需要udf 即可使用substring,这是一种更简洁、更快捷的方式:

>>> from pyspark.sql import functions as f
>>> df.show()
+-------+
|   data|
+-------+
|ABC1234|
|DEF2345|
|GHI3456|
+-------+

>>> df.withColumn("sub_str", f.substring("data", 1, 2)).show()
+-------+-------+
|   data|sub_str|
+-------+-------+
|ABC1234|     AB|
|DEF2345|     DE|
|GHI3456|     GH|
+-------+-------+ 

【讨论】:

可以避免的时候不要使用udf-s +1【参考方案2】:

如果您需要为此使用udf,您也可以尝试以下操作:

input_data = spark.createDataFrame([
    (1,"ABC1234"), 
    (2,"DEF2345"),
    (3,"GHI3456")
], ("id","col0"))

from pyspark.sql.functions import udf
from pyspark.sql.types import StringType

udf1 = udf(lambda x:x[0:2],StringType())
df.withColumn('sub_str',udf1('col0')).show()

+---+-------+-------+
| id|   col0|sub_str|
+---+-------+-------+
|  1|ABC1234|     AB|
|  2|DEF2345|     DE|
|  3|GHI3456|     GH|
+---+-------+-------+

但是,正如 Mohamed Ali JAMAOUI 所写 - 您可以在这里轻松地不使用 udf。

【讨论】:

以上是关于Pyspark 子字符串在 UDF 内部不起作用的主要内容,如果未能解决你的问题,请参考以下文章

excel UDF在工作表中使用时不起作用

正在分析的 pyspark udf 打印行

Pyspark UDF 无法使用大字典

从 foreach 内部调用 Pyspark 保存不起作用

CSS子组合器(>)不起作用[重复]

子字符串编译但代码不起作用[关闭]