如何将spark / scala中数据框的一列值相加

时间:2016-05-04 15:25:36

标签: scala apache-spark

我有一个Dataframe,我从CSV文件中读取了很多列,如:timestamp,steps,heartrate等。

我想对每列的值求和,例如“steps”列上的步骤总数。

据我所知,我想使用这些功能: http://spark.apache.org/docs/latest/api/scala/index.html#org.apache.spark.sql.functions$

但我可以理解如何使用函数sum。

当我写下以下内容时:

val df = CSV.load(args(0))
val sumSteps = df.sum("steps") 

函数sum无法解析。

我是否错误地使用了函数sum? 是否需要先使用功能图?如果是的话怎么样?

一个简单的例子非常有用!我最近开始写Scala。

5 个答案:

答案 0 :(得分:75)

您必须先导入功能:

import org.apache.spark.sql.functions._

然后你可以像这样使用它们:

val df = CSV.load(args(0))
val sumSteps =  df.agg(sum("steps")).first.get(0)

如果需要,您也可以投射结果:

val sumSteps: Long = df.agg(sum("steps").cast("long")).first.getLong(0)

修改

对于多列(例如“col1”,“col2”,...),您可以立即获得所有聚合:

val sums = df.agg(sum("col1").as("sum_col1"), sum("col2").as("sum_col2"), ...).first

<强> EDIT2:

为了动态应用聚合,可以使用以下选项:

  • 一次应用于所有数字列:
df.groupBy().sum()
  • 应用于数字列名称列表:
val columnNames = List("col1", "col2")
df.groupBy().sum(columnNames: _*)
  • 应用具有别名和/或强制转换的数字列名称列表:
val cols = List("col1", "col2")
val sums = cols.map(colName => sum(colName).cast("double").as("sum_" + colName))
df.groupBy().agg(sums.head, sums.tail:_*).show()

答案 1 :(得分:16)

如果您想sum一列的所有值,使用DataFrame的内部RDDreduce会更有效。

import sqlContext.implicits._
import org.apache.spark.sql.functions._

val df = sc.parallelize(Array(10,2,3,4)).toDF("steps")
df.select(col("steps")).rdd.map(_(0).asInstanceOf[Int]).reduce(_+_)

//res1 Int = 19

答案 2 :(得分:4)

只需在列

上应用聚合函数 Sum 即可
df.groupby('steps').sum().show()

按照文档http://spark.apache.org/docs/2.1.0/api/python/pyspark.sql.html

进行操作

请查看此链接https://www.analyticsvidhya.com/blog/2016/10/spark-dataframe-and-operations/

答案 3 :(得分:0)

不确定是否在询问此问题时出现,但是:

df.describe().show("columnName")

在列上给出均值,计数,标准差统计。我认为,只要您执行.show()

,它就会在所有列上返回

答案 4 :(得分:0)

使用spark sql查询。以防万一它对任何人都有用!

import org.apache.spark.sql.SparkSession 
import org.apache.spark.SparkConf 
import org.apache.spark.sql.functions._ 
import org.apache.spark.SparkContext 
import java.util.stream.Collectors

val conf = new SparkConf().setMaster("local[2]").setAppName("test")
val spark = SparkSession.builder.config(conf).getOrCreate()
val df = spark.sparkContext.parallelize(Seq(1, 2, 3, 4, 5, 6, 7)).toDF()

df.createOrReplaceTempView("steps")
val sum = spark.sql("select  sum(steps) as stepsSum from steps").map(row => row.getAs("stepsSum").asInstanceOf[Long]).collect()(0)
println("steps sum = " + sum) //prints 28