2017-01-20 35 views
6
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")) 

Vì vậy, tôi có một khung dữ liệu tia lửa với 3 cột.spark dataframe groupby nhiều lần

Yêu cầu của tôi thực sự là tôi cần thực hiện hai cấp độ nhóm như được giải thích bên dưới.

Cấp 1: Nếu tôi làm nhóm trên col1 và thực hiện tổng Col3. Tôi sẽ nhận được dưới hai cột. 1. col1 2. tổng (col3) Tôi sẽ mất col2 ở đây.

Cấp 2: Nếu tôi muốn nhóm lại bằng col1 và col2 và thực hiện tổng Col3, tôi sẽ nhận được dưới 3 cột. 1. col1 2. col2 3. sum (col3)

Yêu cầu của tôi thực sự là tôi cần phải thực hiện hai cấp độ của groupby và có hai cột này (sum (col3) của level1, sum (col3) của level2) trong một khung dữ liệu cuối cùng.

Làm cách nào tôi có thể thực hiện việc này, bất kỳ ai cũng có thể giải thích?

spark: 1.6.2 Scala: 2.10

Trả lời

8

Một lựa chọn là để làm hai tổng riêng và sau đó tham gia cùng họ trở lại:

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

Một lựa chọn khác là sử dụng các chức năng cửa sổ , xem xét thực tế là level1_sum là tổng của level2_sum được nhóm theo 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| 
+----+----+----------+----------+ 
+1

Seq ("col1") có phải là chìa khóa khi tham gia không? – Ramesh

+1

Có, 'Seq (" col1 ")' chỉ định khóa kết nối. – Psidom

+0

Khi tôi thực hiện điều này, tôi thấy hai trao đổi, một cho groupBy, và một cho cửa sổ. Có cách nào để tránh trao đổi thứ hai không? Nó có vẻ như một khi bạn đã thực hiện groupBy ("col1", "col2"), nó không cần thiết để di chuyển dữ liệu xung quanh cho bước thứ hai - ngoại trừ nếu một số nhóm col1 đi qua các nút. –

Các vấn đề liên quan