2016-05-04 13 views
9

Ho un dataframe che ho letto da un file CSV con molte colonne come: timestamp, passi, frequenza cardiaca eccCome sommare i valori di una colonna di una dataframe scintille/Scala

voglio sommare il valori di ciascuna colonna, ad esempio il numero totale di passaggi sulla colonna "steps".

Per quanto vedo voglio usare questo tipo di funzioni: http://spark.apache.org/docs/latest/api/scala/index.html#org.apache.spark.sql.functions$

ma posso capire come utilizzare la funzione sum.

Quando scrivo la seguente:

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

la somma funzione non può essere risolto.

È possibile utilizzare la somma della funzione in modo errato? È necessario utilizzare prima la mappa delle funzioni? e se sì come?

Un semplice esempio sarebbe molto utile! Ho iniziato a scrivere Scala di recente.

risposta

9

Se si desidera che sum tutti i valori di una colonna, è più efficiente utilizzare DataFrame interno RDD e reduce.

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

Nizza opzione! È ancora più efficiente se vuole la somma di molte colonne? In un dataframe so che sarebbe come 'df.agg (sum (" col1 "), sum (" col2 "), ...)' –

+0

@DanieldePaula So che ha detto ** una colonna ** –

+1

Oh, Ho letto "Voglio sommare i valori di ogni colonna (...)" e ho pensato che intendesse molte colonne. Ad ogni modo, la mia domanda era più per curiosità, per aiutare a migliorare le nostre risposte. –

53

È innanzitutto necessario importare le funzioni:

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

Poi si possono usare in questo modo:

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

È anche possibile lanciare il risultato, se necessario:

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

Modifica:

Per più colonne (ad es. "Col1", "col2", ...), si potrebbe ottenere tutte le aggregazioni in una volta:

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

Edit2:

Per l'applicazione in modo dinamico le aggregazioni, sono disponibili le seguenti opzioni:

  • applicabili a tutte le colonne numeriche in una volta:
df.groupBy().sum() 
  • Applicando a un elenco di nomi di colonne numeriche:
val columnNames = List("col1", "col2") 
df.groupBy().sum(columnNames: _*) 
  • Applicando a un elenco di nomi di colonna numerici con alias e/o calchi:
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()