Получить сумму столбца в "val" (переменная) - PullRequest
0 голосов
/ 25 мая 2019

Я выполняю агрегацию в кадре данных для расчета процента. Мне нужно хранить сумму каждого столбца в отдельной переменной, и я могу использовать это в делении, чтобы вычислить процент

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

Этот код дает сумму, но она будет сохранена как объект dataframe, и ее нельзя будет использовать для деления. Тип:

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

Как я могу сохранить его как постоянное или двойное значение, чтобы я мог использовать его на более поздней стадии агрегации?

Ответы [ 2 ]

1 голос
/ 25 мая 2019

Чтобы получить доступ к фактическому значению в кадре данных как Double, вам нужно собрать кадр данных в драйвер, используя collect.Функция вернет массив со всеми строками, см. Документацию .

Поскольку у вас есть фрейм данных, он будет содержать 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
0 голосов
/ 25 мая 2019

Сначала давайте создадим фрейм данных:

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

...