1. ホーム
  2. scala

[解決済み] データフレームを複数回グループ化する

2022-02-19 02:50:06

質問

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 dataframeを持っています。

+----+----+----+
|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|
+----+----+----+

私の要件は、実際には、私は以下の説明のように2つのレベルのgroupbyを実行する必要があります。

レベル1: col1 で groupby を行い、col3 の合計を行う場合。以下の2つのカラムが得られます。 1. col1 2. 合計(col3) ここで、col2が抜けてしまいます。

レベル2 col1、col2を再度group byし、col3のsumを求めると、以下の3つのカラムが得られます。 1. col1 2. col2 3. 合計(col3)

私の要件は、実際には2つのレベルのgroupByを実行し、最終的に1つのデータフレームにこれらの2つの列(レベル1のsum(col3)、レベル2のsum(col3))を持つ必要があることです。

どうすればいいのでしょうか、どなたか説明してください。

スパーク : 1.6.2 スカラ : 2.10

解決方法は?

1つの方法として、2つの合計を別々に行い、それらを再び結合することができます。

(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 が level2_sum のグループ化された和であることを考慮し、窓関数を使用する方法もあります。 col1 :

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|
+----+----+----------+----------+