Spark UDF 空处理

问题描述 投票:0回答:1

我正在努力处理 UDF 中的空值,该 UDF 对由浮点结构组成的数据帧(源自配置单元表)进行操作:

数据框 (

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 来检查结构以及 x 和 y 是否为空?

我使用的是spark 1.6.1

更新: 与这个问题相反,我正在处理浮点数而不是字符串(在scala中字符串可以为空,浮点数则不能)

scala apache-spark udf
1个回答
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)
})
© www.soinside.com 2019 - 2024. All rights reserved.