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) 代码