【问题标题】:How to CROSS JOIN 2 dataframe?如何交叉连接 2 数据框?
【发布时间】:2021-01-11 20:59:18
【问题描述】:

我正在努力获得 2 个数据框的 CROSS JOIN。我正在使用火花 2.0。如何使用 2 个数据框实现 CROSSS JOIN?

编辑:

val df=df.join(df_t1, df("Col1")===df_t1("col")).join(df2,joinType=="cross join").where(df("col2")===df2("col2"))

【问题讨论】:

  • 向我们展示您的尝试...
  • val df=df.join(df_t1, df("Col1")===df_t1("col")).join(df2,joinType=="cross join").where(df ("col2")===df2("col2"))

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


【解决方案1】:

如果不需要指定条件,请使用crossJoin

这是工作代码的摘录:

people.crossJoin(area).show()

【讨论】:

    【解决方案2】:

    升级到最新版本的spark-sql_2.11 2.1.0版本并使用Dataset的.crossJoin函数

    【讨论】:

      【解决方案3】:

      在不使用连接条件的情况下调用 join 与另一个数据帧。

      看看下面的例子。 给定第一个数据框的人:

      +---+------+-------+------+
      | id|  name|   mail|idArea|
      +---+------+-------+------+
      |  1|  Jack|j@j.com|     1|
      |  2|Valery|x@v.com|     1|
      |  3|  Karl|k@k.com|     2|
      |  4|  Nick|n@n.com|     2|
      |  5|  Luke|l@f.com|     3|
      |  6| Marek|a@b.com|     3|
      +---+------+-------+------+
      

      和区域的第二个数据框:

      +------+--------------+
      |idArea|      areaName|
      +------+--------------+
      |     1|Amministration|
      |     2|        Public|
      |     3|         Store|
      +------+--------------+
      

      交叉连接由下式简单给出:

      val cross = people.join(area)
      +---+------+-------+------+------+--------------+
      | id|  name|   mail|idArea|idArea|      areaName|
      +---+------+-------+------+------+--------------+
      |  1|  Jack|j@j.com|     1|     1|Amministration|
      |  1|  Jack|j@j.com|     1|     3|         Store|
      |  1|  Jack|j@j.com|     1|     2|        Public|
      |  2|Valery|x@v.com|     1|     1|Amministration|
      |  2|Valery|x@v.com|     1|     3|         Store|
      |  2|Valery|x@v.com|     1|     2|        Public|
      |  3|  Karl|k@k.com|     2|     1|Amministration|
      |  3|  Karl|k@k.com|     2|     2|        Public|
      |  3|  Karl|k@k.com|     2|     3|         Store|
      |  4|  Nick|n@n.com|     2|     3|         Store|
      |  4|  Nick|n@n.com|     2|     2|        Public|
      |  4|  Nick|n@n.com|     2|     1|Amministration|
      |  5|  Luke|l@f.com|     3|     2|        Public|
      |  5|  Luke|l@f.com|     3|     3|         Store|
      |  5|  Luke|l@f.com|     3|     1|Amministration|
      |  6| Marek|a@b.com|     3|     1|Amministration|
      |  6| Marek|a@b.com|     3|     2|        Public|
      |  6| Marek|a@b.com|     3|     3|         Store|
      +---+------+-------+------+------+--------------+
      

      【讨论】:

      • Dataframes 现在有一个名为 crossJoin 的方法用于交叉连接
      【解决方案4】:

      您可能必须在 spark confs 中启用 crossJoin。 示例:

      spark = SparkSession
      .builder
      .appName("distance_matrix")
      .config("spark.sql.crossJoin.enabled",True)
      .getOrCreate()
      

      并使用这样的东西:

      df1.join(df2, <condition>)
      

      【讨论】:

        【解决方案5】:

        如果区域数据很小,您可以通过explode 进行操作,无需改组:

        val df1 = Seq(
            (1,"Jack","j@j.com",1),
            (2,"Valery","x@v.com",1),
            (3,"Karl","k@k.com",2),
            (4,"Nick","n@n.com",2),
            (5,"Luke","l@f.com",3),
            (6,"Marek","a@b.com",3)
        ).toDF("id","name","mail","idArea")
        
        val arr = array(
            Seq(
                    (1,"Amministration"),
                    (2,"Public"),
                    (3,"Store")
                )
            .map(r => struct(lit(r._1).as("idArea"), lit(r._2).as("areaName"))):_*
        )
        
        val cross = df1
            .withColumn("d", explode(arr))
            .withColumn("idArea", $"d.idArea")
            .withColumn("areaName", $"d.areaName")
            .drop("d")
        
        df1.show
        cross.show
        

        输出

        +---+------+-------+------+
        | id|  name|   mail|idArea|
        +---+------+-------+------+
        |  1|  Jack|j@j.com|     1|
        |  2|Valery|x@v.com|     1|
        |  3|  Karl|k@k.com|     2|
        |  4|  Nick|n@n.com|     2|
        |  5|  Luke|l@f.com|     3|
        |  6| Marek|a@b.com|     3|
        +---+------+-------+------+
        
        +---+------+-------+------+--------------+
        | id|  name|   mail|idArea|      areaName|
        +---+------+-------+------+--------------+
        |  1|  Jack|j@j.com|     1|Amministration|
        |  1|  Jack|j@j.com|     2|        Public|
        |  1|  Jack|j@j.com|     3|         Store|
        |  2|Valery|x@v.com|     1|Amministration|
        |  2|Valery|x@v.com|     2|        Public|
        |  2|Valery|x@v.com|     3|         Store|
        |  3|  Karl|k@k.com|     1|Amministration|
        |  3|  Karl|k@k.com|     2|        Public|
        |  3|  Karl|k@k.com|     3|         Store|
        |  4|  Nick|n@n.com|     1|Amministration|
        |  4|  Nick|n@n.com|     2|        Public|
        |  4|  Nick|n@n.com|     3|         Store|
        |  5|  Luke|l@f.com|     1|Amministration|
        |  5|  Luke|l@f.com|     2|        Public|
        |  5|  Luke|l@f.com|     3|         Store|
        |  6| Marek|a@b.com|     1|Amministration|
        |  6| Marek|a@b.com|     2|        Public|
        |  6| Marek|a@b.com|     3|         Store|
        +---+------+-------+------+--------------+
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-07-13
          • 2017-05-11
          • 2016-03-13
          • 1970-01-01
          • 2013-04-03
          • 2012-07-17
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多