参数为空时,Spark Scala UDF 不返回预期值

Posted

技术标签:

【中文标题】参数为空时,Spark Scala UDF 不返回预期值【英文标题】:Spark Scala UDF not returning expected value when the parameters are empty 【发布时间】:2021-06-02 03:14:43 【问题描述】:

我有一个简单的 UDF,它根据输入参数返回一个值,如果参数为空,它不返回默认情况。感谢任何帮助纠正我的理解

import org.apache.spark.sql.functions._
import org.apache.spark.sql.types._

val test = udf((a: Double,b: Double ,c: Boolean) => 
if ((a) >= 6 && !c) 
   
      "smith"
   

else if ( (a) >= 20  && !c) 
 "Fred"

else if (( (a) < 6 ||  (b) < 2) && !c) 
 "Ross"

else 
"NA"

)
 
val ds1 = Seq((1,"test",true),
    (2,"test2",false),
    (3,"teste",false)   
  ).toDF("id","name","flag")

val ds2 = Seq((2,6,4),
  (3,0,0)       
  ).toDF("id","flag2","flag3")

var combined= (ds1.as("n")
.join(ds2.as("p"), $"n.id" === $"p.id","left_outer") 
.select
(
$"n.id",
$"n.name",$"n.flag",$"flag2",$"flag3"
))

combined = combined.withColumn("newcol",test($"flag2",$"flag3",$"flag"))
combined.show(5,false)

    对于 Id 值 =1 的行,udf 应返回“NA”,因为它不符合 UDF 中的任何条件,而是返回 null

    另外,我如何为 ds2 中的 flag2 和 flag3 列填充空 /null 。例如。试过 seq(3,null.asInstanceOf[Double],null.asInstanceOf[Double]),出错了

【问题讨论】:

【参考方案1】:

UDF 由于空值而失败,并且没有执行。对于这些情况,它返回 null。处理组合数据框中的空值。一种选择是将空值替换为 0。

val new_combined = combined.na.fill(0).withColumn("newcol",test($"flag2",$"flag3",$"flag"))
new_combined.show(5,false)

+---+-----+-----+-----+-----+------+
|id |name |flag |flag2|flag3|newcol|
+---+-----+-----+-----+-----+------+
|1  |test |true |0    |0    |NA    |
|2  |test2|false|6    |4    |smith |
|3  |teste|false|0    |0    |Ross  |
+---+-----+-----+-----+-----+------+

https://docs.databricks.com/spark/latest/spark-sql/udf-scala.html

【讨论】:

【参考方案2】:

那么为了您的理解:

Scala 使用Java primitives。 Java 中的DoubleInt 原语必须有值,即null 不可接受。因此,在您的情况下,不会为 1 条目调用 UDF,因为可以看出这些是 Double 类型 - 并且在这种情况下当然是 null。如果您了解这一点,那么您应该能够设计出合适的解决方案。

【讨论】:

以上是关于参数为空时,Spark Scala UDF 不返回预期值的主要内容,如果未能解决你的问题,请参考以下文章

当结构中的所有值都为空时,如何在 Scala spark 中使结构为空?

Spark SQL UDF 使用 df.WithColumn() 返回 scala 不可变映射

如何将复杂的 Java 类对象作为参数传递给 Spark 中的 Scala UDF?

将 spark.sql 查询转换为 spark/scala 查询

udf spark Scala 返回案例类

使用 Option 作为输入参数定义 Spark scala UDF