簡體   English   中英

匯總Spark數據幀的列並創建另一個數據幀

[英]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.headaggs.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM