Scala Dataframe null check for columns


val new_df = df.filter($"type_interne" !== "" || $"type_interne" !== "null")

给出错误值||不是字符串

的成员

当我使用===时,过滤效果很好

val new_df = df.filter($"type_interne" === "" || $"type_interne" === "null")

问题似乎是操作符优先级,尝试使用大括号:

 val new_df = df.filter(($"type_interne" !== "") || ($"type_interne" !== null))

你也可以这样写:

val new_df = df.filter(($"type_interne" !== "") or $"type_interne".isNotNull)

虽然拉斐尔的答案在写作时是完全正确的,但火花在演变……操作符!==自2.0版以来已弃用,但您可以使用=!=,它可以解决上面的优先级问题,而无需使用括号。参见源代码中相应的注释:https://github.com/apache/spark/blob/branch - 2.2 -/- sql/core/src/main/scala/org/apache/spark/sql/column.scala # L319-L320

详细回答:
我还想指出一些一开始对我来说并不明显的东西。有数据框架(DF)和数据集(DS)的概念,它们在上述上下文中的用法也分为:
1)由催化剂解释的字符串(错误只在运行时被捕获)- DF和DScase类NullStrings(n: Int, s: String)

val df = spark.sparkContext.parallelize(Seq(
    (1, "abc"),
    (2, "ABC"),
    (3, null),
    (4, ""))
).toDF("n", "s")
df.filter("s is not null and s != ''").show()
+---+---+
|  n|  s|
+---+---+
|  1|abc|
|  2|ABC|
+---+---+

2)使用Column概念的dataframe语法($spark.implicits._导入)部分编译检查:

df.filter($"s" =!= "" || $"s" =!= null).show() 

,但实际上=!=忽略了空值(参见<=>的空安全比较),因此下面等于

df.filter($"s" =!= "").show()
+---+---+
|  n|  s|
+---+---+
|  1|abc|
|  2|ABC|
+---+---+

3)数据集
val ds = df.as[NullStrings]
ds.filter(r => r.s != null && r.s.nonEmpty).show()
+---+---+
|  n|  s|
+---+---+
|  1|abc|
|  2|ABC|
+---+---+

注意如果你在case类中使用Option,你必须处理它,而不是简单的字符串。

case class NullStringsOption(n: Int, s: Option[String])
val ds1 = df.as[NullStringsOption]
ds1.filter(_.s.exists(_.nonEmpty)).show()

最新更新