2016-08-12 13 views
1

複数の列を持つデータフレームがあります。私は1つの列でグループ化し、他の列をすべて一度集約したい。テーブルに4つの列cust_id、f1、f2、f3があり、cust_idでグループ化してavg(f1)、avg(f2)、および平均(f3)を取得したいとします。テーブルには多くの列があります。何かヒント?Sparkで複数の列を一度に集約する方法

次のコードは良いスタートですが、私は多くの列を持っているので、手動で書き込むことはお勧めできません。

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

[SparkSQL:列のリストに集計関数を適用する]の重複している可能性があります(http://stackoverflow.com/questions/33882894/sparksql-apply-aggregate-functions-to-a-list-of-column) –

答えて

4

たぶん、あなたはcolum名でリストをマッピングしてみてください。必要に応じて

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: _*) 

あるいは、あなたはまた、スキーマと一致し、タイプに基づいて集計を構築することができます

val aggCols = df.schema.collect { 
    case StructField(colName, IntegerType, _, _) => avg(colName).as(colName + "_avg") 
    case StructField(colName, StringType, _, _) => first(colName).as(colName + "_first") 
} 
+0

how私は名付けることができますeの列をf1_avgのようなものにしますか? –

+0

@ H.Z。後に '.as()'を置くだけです。 2番目の例では、関数の直後に '.as()'を置くだけです。 –

+0

それは信じられないほどです!最初の例では '.map(colName => avg(colName).as(colName +" _ avg ")) agg(aggCols:_ *)、agg(aggCols.head、aggCols.tail:_ *)は実行します。純粋な魔法!あなたはそれの背後にある理由を説明していただけますか?どうも。 –

関連する問題