[英]How to perform aggregation (sum) on different columns and group the result based on another column of a spark dataframe?
[英]Sum columns of a Spark dataframe and create another dataframe
我有一個如下數據框 -
我正在嘗試從此創建另一個數據框,其中包含2列 - 列名和每列中的值總和,如下所示 -
到目前為止,我已經嘗試了這個(在Spark 2.2.0中)但是拋出了一個堆棧跟蹤 -
val get_count: (String => Long) = (c: String) => {
df.groupBy("id")
.agg(sum(c) as "s")
.select("s")
.collect()(0)
.getLong(0)
}
val sqlfunc = udf(get_count)
summary = summary.withColumn("sum_of_column", sqlfunc(col("c")))
還有其他方法可以完成這項任務嗎?
我認為最有效的方法是進行聚合,然后構建新的數據幀。 這樣你就可以避免代價高昂的explode
。
首先,讓我們創建數據幀。 順便說一句,當你提出問題時提供代碼總是很好。 這樣我們就可以在幾秒鍾內重現您的問題。
val df = Seq((1, 1, 0, 0, 1), (1, 1, 5, 0, 0),
(0, 1, 0, 6, 0), (0, 1, 0, 4, 3))
.toDF("output_label", "ID", "C1", "C2", "C3")
然后我們構建我們感興趣的列列表,聚合並計算結果。
val cols = (1 to 3).map(i => s"C$i")
val aggs = cols.map(name => sum(col(name)).as(name))
val agg_df = df.agg(aggs.head, aggs.tail :_*) // See the note below
agg_df.show
+---+---+---+
| C1| C2| C3|
+---+---+---+
| 5| 10| 4|
+---+---+---+
我們幾乎擁有我們需要的東西,我們只需要收集數據並構建一個新的數據幀:
val agg_row = agg_df.first
cols.map(name => name -> agg_row.getAs[Long](name))
.toDF("column", "sum")
.show
+------+---+
|column|sum|
+------+---+
| C1| 5|
| C2| 10|
| C3| 4|
+------+---+
編輯:
注意: df.agg(aggs.head, aggs.tail :_*)
可能看起來很奇怪。 這個想法只是計算在aggs
計算的所有聚合。 人們會期待像df.agg(aggs : _*)
這樣更簡單的東西。 然而, agg
方法的簽名如下:
def agg(expr: org.apache.spark.sql.Column,exprs: org.apache.spark.sql.Column*)
也許要確保至少使用一列,這就是你需要在aggs.head
和aggs.tail
拆分aggs
aggs.tail
。
我所做的是定義一個方法來從所需的值創建一個結構:
def kv (columnsToTranspose: Array[String]) = explode(array(columnsToTranspose.map {
c => struct(lit(c).alias("k"), col(c).alias("v"))
}: _*))
此函數接收要轉置的列列表(在您的情況下為最后3列)並在結構中將它們轉換為列名作為鍵,列值作為值
然后使用該方法創建一個結構並根據需要進行處理
df.withColumn("kv", kv(df.columns.tail.tail))
.select( $"kv.k".as("column"), $"kv.v".alias("values"))
.groupBy("column")
.agg(sum("values").as("sum"))
首先應用先前定義的函數以使所需的列成為所述結構,然后解構結構以在每行中具有列鍵和列值。 然后,您可以按列名聚合並對值求和
INPUT
+------------+---+---+---+---+
|output_label| id| c1| c2| c3|
+------------+---+---+---+---+
| 1| 1| 0| 0| 1|
| 1| 1| 5| 0| 0|
| 0| 1| 0| 6| 0|
| 0| 1| 0| 4| 3|
+------------+---+---+---+---+
OUTPUT
+------+---+
|column|sum|
+------+---+
| c1| 5|
| c3| 4|
| c2| 10|
+------+---+
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.