按值过滤数据帧不存在于其他数据帧的列中

时间:2016-10-25 16:17:21

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

用这一个敲我的脑袋,我怀疑答案很简单。给定两个数据帧,我想过滤第一列,其中一列中的值不存在于另一个数据帧的列中。

我想这样做而不需要使用完整的Spark SQL,所以只需使用DataFrame.filter,或Column.contains或“isin”关键字,或其中一种连接方法。

val df1 = Seq(("Hampstead", "London"), 
              ("Spui", "Amsterdam"), 
              ("Chittagong", "Chennai")).toDF("location", "city")
val df2 = Seq(("London"),("Amsterdam"), ("New York")).toDF("cities")

val res = df1.filter(df2("cities").contains("city") === false)
// doesn't work, nor do the 20 other variants I have tried

有人有任何想法吗?

2 个答案:

答案 0 :(得分:5)

我发现我可以使用更简单的方法解决这个问题 - 似乎反连接可以作为连接方法的参数,但Spark Scaladoc没有描述它:

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

val df1 = Seq(("Hampstead", "London"), 
              ("Spui", "Amsterdam"), 
              ("Chittagong", "Chennai")).toDF("location", "city")
val df2 = Seq(("London"),("Amsterdam"), ("New York")).toDF("cities")

df1.join(df2, df1("city") === df2("cities"), "leftanti").show

结果:

+----------+-------+ 
|  location|   city| 
+----------+-------+ 
|Chittagong|Chennai| 
+----------+-------+  

P.S。感谢指向副本的指针 - 正确标记为

答案 1 :(得分:2)

如果您尝试使用其他人过滤DataFrame,则应使用join(或其任何变体)。如果你需要的是使用List或适合你的主人和工人的任何数据结构来过滤它,你可以广播它,然后在filterwhere方法中引用它。 / p>

例如,我会做类似的事情:

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

val df1 = Seq(("Hampstead", "London"), 
              ("Spui", "Amsterdam"), 
              ("Chittagong", "Chennai")).toDF("location", "city")
val df2 = Seq(("London"),("Amsterdam"), ("New York")).toDF("cities")

df2.join(df1, joinExprs=df1("city") === df2("cities"), joinType="full_outer")
   .select("city", "cities")
   .where(isnull($"cities"))
   .drop("cities").show()