Spark/Scala - 无法执行用户定义的函数

Posted

技术标签:

【中文标题】Spark/Scala - 无法执行用户定义的函数【英文标题】:Spark/Scala - Failed to execute user defined function 【发布时间】:2020-06-22 12:50:55 【问题描述】:

我有以下有效的代码。

val locList = Source.fromInputStream(getClass.getResourceAsStream("/locations.txt")).getLines().toList

def locCheck(col: String): Boolean = locList.contains(col)
def locUDF = udf[Boolean, String](locCheck)

但是当我添加一个toUpperCase 来实现它时

val locList = Source.fromInputStream(getClass.getResourceAsStream("/locations.txt")).getLines().toList

def locCheck(col: String): Boolean = locList.contains(col.toUpperCase)
def locUDF = udf[Boolean, String](locCheck)

我遇到了由java.lang.NullPointerException引起的Failed to execute user defined function

我使用 udf 作为df.filter(locUDF('location)).count()

我在这里做错了什么,我该如何解决?

【问题讨论】:

你能分享你使用udf函数的完整代码吗? @koiralo 我已经添加了调用 udf 的代码 确保location 列中没有空值,如果location 为空,那么col 为空并在col.toUpperCase 中抛出NPE @koiralo,我确实有空值。我该如何处理它们? 【参考方案1】:

函数或udf 没有任何问题。问题在于进入udf 的数据。

在您的情况下,如果列 location 具有 null 值,当您将这些值传递给 udf 时,col 的值是 null

如果 col 为空,当您调用 col.toUpperCase 时,您会得到一个 NullPointerException

你可以简单地检查函数中的空值

def locCheck(col: String): Boolean = if (col == null) false else locList.contains(col.toUpperCase)

或者你可以使用 Options 来处理这个

def locCheck(col: String): Boolean =locList.contains(Option(col).map(_.toUpperCase))

希望这会有所帮助!

【讨论】:

是的,所有列似乎都有相同的问题 修复它,源数据有一些影响 inputStream 的非 ascii 字符。解决此问题后,您处理 null 的解决方案效果很好。谢谢!

以上是关于Spark/Scala - 无法执行用户定义的函数的主要内容,如果未能解决你的问题,请参考以下文章

将 DataFrame 的数据带回本地节点以在 spark/scala 中执行进一步操作(计数/显示)

Spark/Scala:仅使用 RDD 使用 ReduceByKey 创建嵌套结构

在 Bash 脚本中执行 Apache Spark (Scala) 代码

使用 Glue 连接和 spark scala 覆盖 Mysql 表

Spark,Scala在从文件读取后无法正确创建视图

Spark Scala 程序中的隐含功能不起作用