Spark Scala groupBy (cols) .agg (20 функций суммирования), как использовать map для упрощения 20 функций agg? - PullRequest
2 голосов
/ 10 мая 2019

Допустим, список из Seq("a", "b", "c") и eventDF,

eventDF.groupBy("date").agg(sum("a"), sum("b"), sum("c")) works fine. 

В другом случае у меня есть список из 26 столбцов

val alpha = Seq("a", ... "z"). 

Я имею в виду, что перечислять все слишком беспорядочно26 sum () функция агрегации.

я пытаюсь сделать следующее:

def sumAgg = (colName: String) => sum(colName)

eventDF.groupBy("date").agg(alpha.map(sumAgg(_))), 

кажется, что agg () не может принять список Seq в качестве параметров .....

1 Ответ

1 голос
/ 10 мая 2019

Попробуйте с помощью .map получить всю сумму агрегации для всех столбцов, а затем преобразовать как toMap

Example:

val df =Seq((1,2,3), (3,4,5),(1,1,1), (3,2,2))
        .toDF("A", "B", "C")

val sum_expr=Seq("B","C").map((_ -> "sum")).toMap

df.groupBy('A).agg(sum_expr).show(false)
* +1012 *Result:
+---+------+------+
|  A|sum(B)|sum(C)|
+---+------+------+
|  1|     3|     4|
|  3|     6|     7|
+---+------+------+

Обновление:

val sum_alias=Seq("B", "C").map(c=>sum(c).as(s"sum_$c")) //returns List with alias for column

Поскольку .agg() принимает строку, карту, столбец, .head возвращает string и tail возвращает список и конвертирует в string use : _*.

Было бы легче понять, если бы мы использовали eclipse maven project (intellisense), чтобы получить все функции и параметры, принимаемые функциями.

enter image description here

df_ppp.groupBy('A).agg(sum_alias.head,sum_alias.tail: _*).show(false)

Result:

+---+-----+-----+
|A  |sum_B|sum_C|
+---+-----+-----+
|1  |3    |4    |
|3  |6    |7    |
+---+-----+-----+
...