如何处理原始可空类型的Spark UDF输入/输出

Art*_*tov 3 sql null apache-spark udf

问题:

1)如果输入是包含null以下内容的原始类型的列,Spark不会调用UDF :

inputDF.show()

+-----+
|  x  |
+-----+
| null|
|  1.0|
+-----+

inputDF
  .withColumn("y",
     udf { (x: Double) => 2.0 }.apply($"x") // will not be invoked if $"x" == null
  )
  .show()

+-----+-----+
|  x  |  y  |
+-----+-----+
| null| null|
|  1.0|  2.0|
+-----+-----+
Run Code Online (Sandbox Code Playgroud)

2)无法null从UDF 生成原始类型的列:

udf { (x: String) => null: Double } // compile error

Art*_*tov 7

因此,以该文档:

请注意,如果使用原始参数,则无法检查它是否为null,如果原语输入为null,UDF将为您返回null.如果您想自己进行空值处理,请使用盒装类型或[[选项]].


因此,最简单的解决方案就是使用盒装类型,如果你的UDF输入是基本类型的可空列OR/AND你需要从UDF输出null作为基本类型的列:

inputDF
  .withColumn("y",
     udf { (x: java.lang.Double) => 
       (if (x == null) 1 else null): java.lang.Integer
     }.apply($"x")
  )
  .show()

+-----+-----+
|  x  |  y  |
+-----+-----+
| null| null|
|  1.0|  2.0|
+-----+-----+
Run Code Online (Sandbox Code Playgroud)

  • 请注意,您引用的文档有点误导:虽然`Option`可用于返回"可空"原语,但是`Option`不能用作UDF的输入(至少在Spark 1.6中,不确定2.0) (3认同)