【问题标题】:spark dataframe groupby multiple times多次触发数据帧 groupby
【发布时间】:2017-06-05 21:29:36
【问题描述】:
val df = (Seq((1, "a", "10"),(1,"b", "12"),(1,"c", "13"),(2, "a", "14"),
              (2,"c", "11"),(1,"b","12" ),(2, "c", "12"),(3,"r", "11")).
          toDF("col1", "col2", "col3"))

所以我有一个包含 3 列的 spark 数据框。

+----+----+----+
|col1|col2|col3|
+----+----+----+
|   1|   a|  10|
|   1|   b|  12|
|   1|   c|  13|
|   2|   a|  14|
|   2|   c|  11|
|   1|   b|  12|
|   2|   c|  12|
|   3|   r|  11|
+----+----+----+

我的要求实际上是我需要执行两个级别的groupby,如下所述。

1 级: 如果我在 col1 上做 groupby 并做 Col3 的总和。我将低于两列。 1. col1 2.总和(col3) 我将在这里松开 col2。

2 级: 如果我想再次对 col1 和 col2 进行分组并计算 Col3 的总和,我将得到 3 列以下。 1. col1 2. col2 3. sum(col3)

我的要求实际上是我需要执行两个级别的 groupBy 并将这两列(level1 的 sum(col3),level2 的 sum(col3))放在最后一个数据帧中。

我该怎么做,谁能解释一下?

火花:1.6.2 斯卡拉:2.10

【问题讨论】:

    标签: scala apache-spark


    【解决方案1】:

    一种选择是分别对两者求和,然后将它们合并:

    (df.groupBy("col1", "col2").agg(sum($"col3").as("sum_level2")).
        join(df.groupBy("col1").agg(sum($"col3").as("sum_level1")), Seq("col1")).show)
    
    +----+----+----------+----------+
    |col1|col2|sum_level2|sum_level1|
    +----+----+----------+----------+
    |   2|   c|      23.0|      37.0|
    |   2|   a|      14.0|      37.0|
    |   1|   c|      13.0|      47.0|
    |   1|   b|      24.0|      47.0|
    |   3|   r|      11.0|      11.0|
    |   1|   a|      10.0|      47.0|
    +----+----+----------+----------+
    

    另一个选择是使用窗口函数,考虑到 level1_sum 是由col1 分组的 level2_sum 的总和:

    import org.apache.spark.sql.expressions.Window
    val w = Window.partitionBy($"col1")
    
    (df.groupBy("col1", "col2").agg(sum($"col3").as("sum_level2")).
        withColumn("sum_level1", sum($"sum_level2").over(w)).show)
    
    +----+----+----------+----------+
    |col1|col2|sum_level2|sum_level1|
    +----+----+----------+----------+
    |   1|   c|      13.0|      47.0|
    |   1|   b|      24.0|      47.0|
    |   1|   a|      10.0|      47.0|
    |   3|   r|      11.0|      11.0|
    |   2|   c|      23.0|      37.0|
    |   2|   a|      14.0|      37.0|
    +----+----+----------+----------+
    

    【讨论】:

    • Seq("col1") 这是加入时的键吗?
    • 是的,Seq("col1") 指定加入密钥。
    • 执行此操作时,我看到两个交换,一个用于 groupBy,一个用于 Window。有没有办法避免第二次交换?似乎一旦你完成了 groupBy("col1","col2"),就不需要为第二步移动数据——除非某些 col1 组跨越节点。
    • 请参阅new question 了解我上面的问题。
    猜你喜欢
    • 2015-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多