【问题标题】:Group By two different keys in two different DataFrames using Spark Scala without join使用 Spark Scala 在两个不同的 DataFrames 中按两个不同的键分组,无需连接
【发布时间】:2017-11-17 02:25:29
【问题描述】:

我是 Spark Scala 的新手,我想使用两个数据帧或 RDD 计算相似性变量。我没有他们两个之间的共同键,我做了一个笛卡尔连接,但加入的 Df 很大。是否可以从两个 DF 计算一个新变量而不加入它们?

例如:

df1.show
+----+------------+------+
| id1|        food| level|
+----+------------+------+
|id11|       pasta| first|
|id11|       pizza|second|
|id11|   ice cream| first|
|id12|     spanish| first|
|id12|   ice cream|second|
|id13|      fruits| first|
+----+------------+------+
df2.show
+----+---------+
| id2|     food|
+----+---------+
|id21|    pizza|
|id21|   fruits|
|id22|    pasta|
|id22|    pizza|
|id22|ice cream|
+----+---------+

对于来自 df1 的每个 id1,我想循环来自 df2 的食物变量,按 id2 分组。
我想得到这个输出:

+----+----+----------------+
| id1| id2|count_similarity|
+----+----+----------------+
|id11|id21|               1|id11 and id21 have only "pizza' in common
|id11|id22|               3|
|id12|id21|               0|
|id12|id22|               1|
|id13|id21|               1|
|id13|id22|               0|
+----+----+----------------+

是否可以在 RDD 上使用 map 语句来计算? 谢谢

【问题讨论】:

    标签: scala apache-spark rdd


    【解决方案1】:

    可以将两个数据框都转换为rdd,使用cartesian方法计算每个id对之间的相似度,然后重构数据框:

    case class similarity(id1: String, id2: String, count_similarity: Int)
    
    val rdd1 = df1.rdd.groupBy(_.getString(0)).mapValues(_.map(_.getString(1)).toList)    
    val rdd2 = df2.rdd.groupBy(_.getString(0)).mapValues(_.map(_.getString(1)).toList)
    
    rdd1.cartesian(rdd2).map{ 
        case (x, y) => similarity(x._1, y._1, x._2.intersect(y._2).size) 
    }.toDF.orderBy("id1").show
    
    +----+----+----------------+
    | id1| id2|count_similarity|
    +----+----+----------------+
    |id11|id22|               3|
    |id11|id21|               1|
    |id12|id21|               0|
    |id12|id22|               1|
    |id13|id21|               1|
    |id13|id22|               0|
    +----+----+----------------+
    

    【讨论】:

    • 感谢 Psidom 回答我的问题
    【解决方案2】:

    这对你有用吗?

    df1.registerTempTable("temp_table_1")
    df2.registerTempTable("temp_table_2")
    
    spark.sql(
      """SELECT id1, id2, count(*) AS count_similarity FROM temp_table_1 AS t1
       | JOIN temp_table_2 AS t2 ON (t1.food = t2.food)
       | GROUP BY id1, id2
       | ORDER BY id1, id2""".stripMargin
    ).show
    

    【讨论】:

      猜你喜欢
      • 2020-09-06
      • 2016-07-18
      • 1970-01-01
      • 1970-01-01
      • 2021-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-16
      相关资源
      最近更新 更多