将列的总和放入 "val"(变量)

Get sum of a column into a "val" (variable)

我正在数据框中执行聚合以计算百分比。我需要将每列的总和存储在一个单独的变量中,我可以在除法中使用它来计算百分比

val sumOfCol1 = df.agg(round(sum("col1"),2))

此代码给出了总和,但它将作为数据框对象存储,不能用于除法。类型是:

sumOfCol1: org.apache.spark.sql.DataFrame = [round(sum(col1), 2): double]

如何将其存储为常量或双精度值,以便在聚合的后期使用它?

要以 Double 的形式访问数据帧中的实际值,您需要使用 collect 将数据帧收集到驱动程序。该函数将 return 一个包含所有行的数组,参见 documentation

由于您有一个数据框,它将包含 Row 个对象,您必须使用 getAs 来访问实际的基础值。更直观的方法是先转换为数据集,然后收集:

val sumOfCol1 = df.agg(round(sum("col1"),2)).as[Double].collect()(0)

在这种情况下,因为你只需要一个值,你也可以使用first方法:

val sumOfCol1 = df.agg(round(sum("col1"),2)).as[Double].first

首先让我们创建一个数据框:

import org.apache.spark.sql._
import org.apache.spark.sql.types._

val schema = List(
  StructField("col1", IntegerType, true),
  StructField("col2", IntegerType, true),
  StructField("col3", IntegerType, true)
)

val data=Seq(Row(10,100,1000),Row(20,200,2000),Row(30,300,3000))


val df = spark.createDataFrame(spark.sparkContext.parallelize(data),StructType(schema))
df.show()

+----+----+----+
|col1|col2|col3|
+----+----+----+
|  10| 100|1000|
|  20| 200|2000|
|  30| 300|3000|
+----+----+----+

现在我们有了数据框。 我们可以在赋值时使用模式匹配来收集想要的结果。由于 df.first() returns 一个 Row 对象,我们可以这样做:

val cols = df.columns.toList
val sums = cols.map(c => round(sum(c),2).cast("double"))

val Row(sumCol1: Double, sumCol2: Double, sumCol3: Double) = df.groupBy().agg(sums.head, sums.tail:_*).first()

sumCol1: Double = 60.0
sumCol2: Double = 600.0
sumCol3: Double = 6000.0