Pyspark:如何处理python用户定义函数中的空值

2024-10-02 16:30:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我想使用一些不是pyspark固有的字符串相似性函数,比如数据帧上的jaro和jaro winkler度量。这些在python模块中很容易获得,比如jellyfish。我可以为没有null值的情况编写pyspark udf's fine,即比较猫和狗。当我将这些udf应用于存在null值的数据时,它不起作用。在像我正在解决的问题中,其中一个字符串是null是非常常见的

我需要帮助使我的字符串相似性udf正常工作,更具体地说,在其中一个值是null的情况下工作

我编写了一个udf,当输入数据中没有空值时,它可以工作:

from pyspark.sql.functions import udf
from pyspark.sql.types import DoubleType
import pyspark.sql.functions as F
import jellyfish.cjellyfish

def jaro_winkler_func(df, column_left, column_right):

    jaro_winkler_udf = udf(f=lambda s1, s2: jellyfish.jaro_winkler(s1, s2), returnType=DoubleType())

    df = (df
          .withColumn('test',
                      jaro_winkler_udf(df[column_left], df[column_right])))

    return df

输入和输出示例:

^{pr2}$
+-----------+------------+------------------+
|string_left|string_right|              test|
+-----------+------------+------------------+
|       dude|         dud|0.9166666666666666|
|       spud|         dud|0.7222222222222222|
+-----------+------------+------------------+

当我在一个空值的数据上运行这个函数时,我会得到大量的spark错误,最适用的似乎是TypeError: str argument expected。我假设这是由于数据中的null值造成的,因为它在没有值时起作用。在

我修改了上面的函数来检查两个值是否都不为null,并且只有在这种情况下才运行函数,否则返回0。在

from pyspark.sql.functions import udf
from pyspark.sql.types import DoubleType
import pyspark.sql.functions as F
import jellyfish.cjellyfish

def jaro_winkler_func(df, column_left, column_right):

    jaro_winkler_udf = udf(f=lambda s1, s2: jellyfish.jaro_winkler(s1, s2), returnType=DoubleType())

    df = (df
       .withColumn('test',
                   F.when(df[column_left].isNotNull() & df[column_right].isNotNull(),
                          jaro_winkler_udf(df[column_left], df[column_right]))
                   .otherwise(0.0)))

    return df

但是,我仍然得到了和以前一样的错误。在

示例输入和我希望输出的内容:

+-----------+------------+
|string_left|string_right|
+-----------+------------+
|       dude|         dud|
|       spud|         dud|
|       spud|        null|
|       null|        null|
+-----------+------------+
+-----------+------------+------------------+
|string_left|string_right|              test|
+-----------+------------+------------------+
|       dude|         dud|0.9166666666666666|
|       spud|         dud|0.7222222222222222|
|       spud|        null|0.0               |
|       null|        null|0.0               |
+-----------+------------+------------------+

Tags: 数据importrightdfsqlstringcolumnleft
1条回答
网友
1楼 · 发布于 2024-10-02 16:30:10

我们将稍微修改一下您的代码,它应该可以正常工作:

@udf(DoubleType())
def jaro_winkler(s1, s2):
    if not all((s1,s2)):
        out = 0
    else: 
        out = jellyfish.jaro_winkler(s1, s2)
    return out


def jaro_winkler_func(df, column_left, column_right):

    df = df.withColumn(
        'test',
        jaro_winkler(df[column_left], df[column_right]))
    )

    return df

相关问题 更多 >