【问题标题】:Joining two DataFrames in Spark SQL and selecting columns of only one在 Spark SQL 中加入两个 DataFrame 并仅选择一个列
【发布时间】:2016-12-07 20:30:20
【问题描述】:

我在 Spark SQL 中有两个 DataFrame(D1 和 D2)。

我正在尝试内部加入他们两个D1.join(D2, "some column") 并取回仅 D1 的数据,而不是完整的数据集

D1 和 D2 具有相同的列。

有人可以帮我解决这个问题吗?

我使用的是 Spark 1.6。

【问题讨论】:

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


    【解决方案1】:

    假设您想加入“id”列。然后你可以写:

    val sqlContext = new org.apache.spark.sql.SQLContext(sc)
    import sqlContext.implicits._    
    d1.as("d1").join(d2.as("d2"), $"d1.id" === $"d2.id").select($"d1.*")
    

    【讨论】:

    • 嗨,这个答案有帮助。我有一个愚蠢的问题。 $ 符号是什么意思?当我尝试在我的代码中编写 $ 符号时出现错误。
    • 这是访问 DataFrame 列的另一种方式,如 here 所述,但您必须导入implicits 包(我已经编辑了我的答案)
    • 嗯,还有一个“leftsemi”连接选项。它包括左侧表中右侧有匹配行的行。也无需重复数据删除,因为匹配的行只包含一次。
    【解决方案2】:

    作为替代答案,您还可以在不添加别名的情况下执行以下操作:

    d1.join(d2, d1("id") === d2("id"))
      .select(d1.columns.map(c => d1(c)): _*)
    

    【讨论】:

    • 嗨@nsanglar,谢谢,这非常有帮助。但是,如果我有一个像 .withColumn("derived_id", coalesce(d2("id"),d1("id"))) 这样的派生列,并且我想要这个列以及 d1 的所有列,那么我将如何修改 select 语句?
    【解决方案3】:

    你可以使用left_semi:

    d1.as("d1").join(d2.as("d2"), $"d1.id" === $"d2.id", "left_semi")
    

    半连接只取左侧数据集中满足连接条件的行。

    还有另一种有趣的连接类型:left_anti,它的工作方式与 left_semi 类似,但只接受条件满足的那些行。

    【讨论】:

      【解决方案4】:

      您应该使用 leftsemi 连接,这类似于内部连接的不同之处在于 leftsemi 连接返回左侧数据集中的所有列并忽略右侧数据集中的所有列。

      您可以在 Scala 中使用 leftsemi 连接类型尝试以下类似 Join Spark DataFrame 的操作。

      empDF.join(deptDF,empDF("emp_dept_id") ===  deptDF("dept_id"),"leftsemi")
          .show(false)
      

      如果您使用 Python,请使用下面的 PySpark join dataframe 示例

      empDF.join(deptDF,empDF.emp_dept_id ==  deptDF.dept_id,"leftsemi") \
         .show(truncate=False)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-02-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多