【问题标题】:Filter dataframe by value NOT present in column of other dataframe [duplicate]按其他数据框列中不存在的值过滤数据框[重复]
【发布时间】:2016-10-25 16:17:20
【问题描述】:

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

我想在不使用成熟的 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

有人有什么想法吗?

【问题讨论】:

  • 试试下面的代码,它会起作用:- val df3 = Seq(("Hampstead", "London"), ("Spui", "Amsterdam"), ("Chittagong", "Chennai" )).toDF("location", "city") val df4 = Seq(("London"),("Amsterdam"), ("New York")).toDF("cities") df3.where(df3( "城市").isInCollection(df4.map(_.getString(0)).collect())).show()

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


【解决方案1】:

我发现我可以使用更简单的方法来解决这个问题 - 似乎可以将反连接作为 join 方法的参数,但 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| 
+----------+-------+  

附:感谢您提供指向副本的指针 - 已正确标记

【讨论】:

    【解决方案2】:

    如果您尝试使用另一个过滤DataFrame,您应该使用join(或其任何变体)。如果您需要使用List 或任何适合您的master 和worker 的数据结构对其进行过滤,您可以广播它,然后在filterwhere 方法中引用它。

    例如,我会这样做:

    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()
    

    【讨论】:

    • 好的,但是哪个连接会达到我想要的结果?我相信我应该考虑反连接,但根据 Scaladoc,这不是一个选项。另外,我同意我可以在列表上使用过滤器(...类似于 df.filter(($"col" isin ) === false),但是我怎样才能打开我想要引用的列进入列表?
    猜你喜欢
    • 2011-11-14
    • 1970-01-01
    • 2019-12-09
    • 2020-11-16
    • 1970-01-01
    • 2022-11-23
    • 2017-04-22
    • 2017-11-12
    • 1970-01-01
    相关资源
    最近更新 更多