【问题标题】:Spark dataframe filter/where is not working for multiple conditionsSpark数据框过滤器/在多个条件下不起作用
【发布时间】:2020-11-03 15:55:34
【问题描述】:

val someDF = Seq(
  (8, "bat"),
  (64, "mouse"),
  (-27, "horse"),
  (10, null),
  (11, "")
).toDF("number", "word")


使用上面的数据框,我试图过滤掉 null 和空 word 列值。

Trail - 1

someDF.filter(col("word") =!= "" || col("word").isNotNull).show(false)
+------+-----+
|number|word |
+------+-----+
|8     |bat  |
|64    |mouse|
|-27   |horse|
|11    |     |
+------+-----+

我使用了 OR 条件,但它仍然没有删除空字符串 word 列值。


Trail - 2

someDF.filter(col("word") =!= "").filter(col("word").isNotNull).show(false)
+------+-----+
|number|word |
+------+-----+
|8     |bat  |
|64    |mouse|
|-27   |horse|
+------+-----+


在 trail - 2 中,我使用了链式过滤器,然后它从数据框中删除了 null 值和空值。


Trail - 3


someDF.filter(col("word") =!= "" && col("word").isNotNull).show(false)
+------+-----+
|number|word |
+------+-----+
|8     |bat  |
|64    |mouse|
|-27   |horse|
+------+-----+


在路径 -3 中,我使用了 AND 操作,然后它删除了 null/空值。

谁能向我解释为什么 OR 操作不起作用?我的代码有问题吗?

【问题讨论】:

  • 你的代码没有任何问题,我认为你应该检查这个article解释更多细节
  • 我试图过滤空值和空字符串列值。但它不起作用
  • 我正在尝试这样 res35.filter(col("word") =!= "" || col("word").isNotNull).show(false)。但它'不过滤空字符串值
  • 用解释检查所有试用版,看看有什么不同

标签: scala dataframe apache-spark apache-spark-sql


【解决方案1】:

一般而言,Spark SQL(包括 SQL 以及 DataFrame 和 Dataset API)不保证子表达式的求值顺序。特别是,运算符或函数的输入不必从左到右或以任何其他固定顺序进行评估。例如,逻辑 AND 和 OR 表达式没有从左到右的“短路”语义。

因此,依赖布尔表达式的副作用或求值顺序以及 WHERE 和 HAVING 子句的顺序是危险的,因为在查询优化和规划期间可以重新排序此类表达式和子句。具体来说,如果 UDF 依赖 SQL 中的短路语义进行空值检查,则无法保证在调用 UDF 之前会发生空值检查。例如,

现在让我们看看你的例子

轨迹 1: someDF.filter(col("word") =!= "" || col("word").isNotNull).show(false)

它是一个逻辑或运算符,意味着它足以使一侧为真: "" =!= "" -> 假 "".isnotNull -> true

表示空词为真,不应该被过滤掉

trail 2 和 3 与您使用的逻辑和运算符相同 "" =!= "" -> false 足以判断表达式为假,应该被过滤掉。

【讨论】:

  • 澄清一下,这个 someDF.filter(col("word") =!= "") 怎么会从数据框中同时删除 null 和 emtpy 字符串值?
猜你喜欢
  • 2019-01-03
  • 2018-02-09
  • 2020-05-02
  • 1970-01-01
  • 2021-07-26
  • 2021-09-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多