Spark Scala筛选器数据帧,其中值不在另一个数据帧中

Spark Scala筛选器数据帧,其中值不在另一个数据帧中,scala,apache-spark,Scala,Apache Spark,我有两个数据帧:a和b。这就是它们的样子: a ------- v1 string v2 string roughly hundreds of millions rows b ------- v2 string roughly tens of millions rows 我想保留数据帧a中的行,其中v2不在b(“v2”)中 我知道我可以在右边为null的地方使用left join和filter,或者使用带有“not in”结构的SparkSQL。不过,我打赌有更好的方法。使用paird

我有两个数据帧:
a
b
。这就是它们的样子:

a
-------
v1 string
v2 string

roughly hundreds of millions rows


b
-------
v2 string

roughly tens of millions rows
我想保留数据帧
a
中的行,其中
v2
不在
b(“v2”)


我知道我可以在右边为null的地方使用left join和filter,或者使用带有“not in”结构的SparkSQL。不过,我打赌有更好的方法。

使用
pairdd函数。减法键

defsubtractByKey[W](其他:RDD[(K,W)])(隐式arg0:ClassTag[W]):RDD[(K,V)]

返回一个RDD,其中包含来自此RDD的密钥不在其他RDD中的对

(有一些变体提供对分区的控制。请参阅。)


因此,您可以使用的
a.rdd.map{case(v1,v2)=>(v2,v1)}.subtractByKey(b.rdd).toDF

您可以使用的
方法,即“返回包含此数据集中的行但不包含另一个数据集中的行的新数据集”

考虑您的数据帧
a
如下所示

+----+
|col1|
+----+
|  v1|
|  v2|
+----+
+----+
|col1|
+----+
|  v2|
+----+

假设您的数据帧
b
如下所示

+----+
|col1|
+----+
|  v1|
|  v2|
+----+
+----+
|col1|
+----+
|  v2|
+----+


方法1:
--------------

您可以使用dataframe的
join
方法,并使用类型为
left\u anti
的联接来查找dataframe
a
中的值,但不在dataframe
b
中。代码如下:

a.as('a).join(b.as('b),$"a.col1" === $"b.col1","left_anti").show()
请在下面查找结果:



方法2:
--------------

您可以使用类似于sql server/Oracle等的
sql
。为此,首先必须将数据帧注册为临时表(将驻留在spark的内存中),然后在该表的顶部写入sql

a.registerTempTable("table_a")
b.registerTempTable("table_b")
spark.sql("select * from table_a a where not exists(select 1 from table_b b where a.col1=b.col1)").show()
请在下面查找结果:


也许还存在一个基于纯数据帧的解决方案?对不起,我不太使用数据帧。但是跳回RDD应该不会太痛苦,使用
subtractByKey
并返回数据帧。你可以使用啊,
除了
是完美的答案!想把它作为一个单独的答案发布吗?当然,我已经把它作为一个答案发布了。我已经发布了一个答案,但是join+filter应该也能很好地工作!我认为join+filter的大部分工作在任何解决方案中都是不可避免的。是的,实际上SparkSQL工作得非常快。另外-它不是重复的-我需要负过滤器。请参阅