Spark Scala groupBy(cols).agg(20个汇总函数),如何使用map简化20个agg函数?

时间:2019-05-10 03:21:37

标签: scala apache-spark aggregate-functions

比方说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 个答案:

答案 0 :(得分:1)

尝试使用.map获取所有列的所有 sum聚合,然后转换为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)

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()接受String,Map,Column,因此.head返回string,而tail返回list并转换为string use : _*。 / p>

如果我们使用 eclipse maven project (智能)来获取所有函数和函数所接受的参数,将会更容易理解。

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