我正在一个数据帧中执行聚合以进行百分比计算。我需要将每列的总和存储在一个单独的变量中,并且可以在除法中使用它来计算百分比
val sumOfCol1 = df.agg(round(sum("col1"),2))
此代码给出了总和,但是它将被存储为数据帧对象,并且不能用于除法。类型是:
sumOfCol1: org.apache.spark.sql.DataFrame = [round(sum(col1), 2): double]
如何将其存储为常数或双精度值,以便在以后的聚合中使用它?
答案 0 :(得分:1)
要以Double
的形式访问数据帧中的实际值,您需要使用collect
将数据帧收集到驱动程序。该函数将返回一个包含所有行的数组,请参见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
答案 1 :(得分:0)
首先让我们创建一个数据框:
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()
返回了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