我正在处理UDF中的空值,该UDF对数据帧(源自hive表)进行操作,该数据帧由浮点数结构组成:
数据框(points
)具有以下架构:
root
|-- point: struct (nullable = true)
| |-- x: float (nullable = true)
| |-- y: float (nullable = true)
例如,我想计算x和y的总和。请注意,我没有"处理"以下示例中为空值,但我希望能够检查我的udf point
,x
或y
是null
。
第一种方法:
val sum = udf((x:Float,y:Float) => x+y)
points.withColumn("sum",sum($"point.x",$"point.y"))
如果struct
点为null
,则不起作用,在这种情况下永远不会评估udf(udf中的代码永远不会被执行!),结果为null。另外,我无法检查x
或y
是否为空,因为Floats
在scala中不能为空。
第二种方法:
val sum = udf((pt:Row) => pt.getFloat(0)+pt.getFloat(1))
points.withColumn("sum",sum($"point"))
采用这种方法,我可以在我的udf中查看pt
是否为空,但我可以检查x
和y
,因为Floats
不能空值。在这种情况下,我得到NullPointerException
。
我如何编写一个udf win,我可以检查struct,x和y是否为null?
我使用spark 1.6.1
更新: 与this question相比,我处理浮点数而不是字符串(scala中的字符串可以为null,浮点数不是浮点数)
答案 0 :(得分:5)
您可以使用Row.isNullAt(i)
检查i
字段是否为空。在你的情况下,你应该把你的udf写成,
sum = udf((point: Row) => point.match {
case p if (p.isNullAt(0) && p.isNullAt(0)) => 0f
case p if p.isNullAt(0) => p.getFloat(1)
case p if p.isNullAt(1) => p.getFloat(0)
case p => p.getFloat(0) + p.getFloat(1)
})