【问题标题】:Spark/Scala - Failed to execute user defined functionSpark/Scala - 无法执行用户定义的函数
【发布时间】: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,我确实有空值。我该如何处理它们?

标签: scala apache-spark


【解决方案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 的解决方案效果很好。谢谢!
猜你喜欢
  • 2021-12-18
  • 1970-01-01
  • 2019-08-22
  • 2019-08-27
  • 1970-01-01
  • 2014-06-06
  • 2017-07-29
  • 2020-10-15
  • 1970-01-01
相关资源
最近更新 更多