如何在Spark中一次对多个列进行聚合

时间:2016-08-12 19:57:35

标签: scala apache-spark

我有一个包含多列的数据框。我希望按其中一个列进行分组,并将其他列聚合一次。假设该表有4列,cust_id,f1,f2,f3,我想通过cust_id进行分组,然后获得avg(f1),avg(f2)和avg(f3)。该表将包含许多列。任何提示?

以下代码是一个好的开始,但由于我有很多列,因此手动编写它们可能并不是一个好主意。

df.groupBy("cust_id").agg(sum("f1"), sum("f2"), sum("f3"))

1 个答案:

答案 0 :(得分:5)

也许您可以尝试使用列名称映射列表:

DataColumn idColumn = new DataColumn("ID");

DataColumn nameColumn = new DataColumn("Name");
//nameColumn.Unique = true; //SqlBulkCopy does not care about these settings.
//nameColumn.AllowDBNull = false;

DataColumn bulkInsertIDColumn = new DataColumn("BulkInsertID");
//bulkInsertIDColumn.Unique = false;
//bulkInsertIDColumn.AllowDBNull = true;

table.Columns.Add(ID);
table.Columns.Add(nameColumn);
table.Columns.Add(bulkInsertIDColumn);

foreach (string productName in productNames)
{
    DataRow row = table.NewRow();
    //We don't do anything with row[idColumn]
    row[nameColumn] = productName;
    row[bulkInsertIDColumn] = bulkInsertID;
    table.Rows.Add(row);
}

或者,如果需要,您还可以匹配架构并根据类型构建聚合:

val groupCol = "cust_id"
val aggCols = (df.columns.toSet - groupCol).map(
  colName => avg(colName).as(colName + "_avg")
).toList

df.groupBy(groupCol).agg(aggCols.head, aggCols.tail: _*)