想说明Spark

时间:2019-05-10 23:35:15

标签: apache-spark apache-spark-sql

我正在尝试从数据框中过滤不等于多列中的(!=)值的记录。 我能够使其工作,但在解释过滤器的工作方式时遇到了麻烦。

问题陈述

  • 具有id和value列的数据框
  • 过滤不包含的记录 id = 1且value ='Value1'

我可以使用以下代码解决问题

val conf = new SparkConf().setAppName("Test").setMaster("local[4]")    
val spark = org.apache.spark.sql.SparkSession.builder().config(conf).getOrCreate()    
import spark.implicits._

val df = Seq((1, "Value1"),(2, "Value2"), (3, "Value3"), (4, "Value1"), (5, "Value2"), (6, "Value3")).toDF("id", "value")    
df.filter("(id != 1 or value != 'Value1')").show

带有“或”的输出:

+---+------+
| id| value|
+---+------+
|  2|Value2|
|  3|Value3|
|  4|Value1|
|  5|Value2|
|  6|Value3|
+---+------+

带有“ AND”的输出:

它将删除id = 4且值为= Value1的另一条记录。基本上,它将删除所有值为!= Value1的记录。

+---+------+
| id| value|
+---+------+
|  2|Value2|
|  3|Value3|
|  5|Value2|
|  6|Value3|
+---+------+

问题:

最初,我尝试在"df.filter("(id != 1 and value != 'Value1')").show"之类的过滤器中使用“ AND”条件,但此方法不起作用

我的理解是,由于它是两个条件的组合(id not equal 1 and value not equal Value1),因此应为AND 但奇怪的是,它可以在过滤器内部的OR条件下工作。

有人可以解释这种行为以及如何解释。抱歉,如果这是SQL语法问题

2 个答案:

答案 0 :(得分:1)

从逻辑上解释问题陈述

not (id = 1 and value = 'Value1') 

并且您期望它返回不匹配这两个值的所有行。分组很重要

该语句可以在逻辑上转换为

id!=1 or value!="Value1" 

这称为De Morgans Law,并说明您所看到的内容

答案 1 :(得分:1)

您可以在Java中做类似的事情(在Python,Scala中也可以做类似的事情)

ds = ds.filter(functions.not(functions.col(colName).isin(exclusionSet)).
filter(functions.not(functions.col(colName).isin(exclusionSet2));

,然后继续添加所需数量的过滤器。

functions.not方法排除指定的一组值。 .isin方法接受任何Object或Seq,因此您可以指定多个值。