2017-04-03 1 views
1

J'essaie de trouver un moyen de calculer la moyenne de lignes dans une Spark Dataframe dans Scala où je veux ignorer les NA. Dans R, il y a une fonction très pratique appelée rowMeans où l'on peut spécifier à ignorer NAs:Calculer la moyenne des rangées, en ignorant les NA dans Spark Scala

rowmeans(df,na.rm=TRUE) 

Je suis incapable de trouver une fonction correspondante pour Dataframes Spark, et je me demande si quelqu'un a une suggestion ou entrée si ce serait possible. Les remplacer par 0 ne sera pas dû puisque cela affectera le dénominateur.

J'ai trouvé une question similaire here, mais mon dataframe aura des centaines de colonnes.

Toute aide et les idées partagées est appréciée, bravo!

Répondre

2

Habituellement, ces fonctions ignorent les valeurs par défaut. Même s'il existe des colonnes mixtes avec des types numériques et de chaînes, celle-ci supprimera les chaînes et les valeurs nulles, et ne calculera que les valeurs numériques.

df.select(df.columns.map(c => mean(col(c))) :_*).show 
+0

Merci pour vos commentaires. Cependant, je cherche un moyen de calculer la moyenne des lignes dans une base de données. – Chooan

+0

Sry, j'ai confondu les rangées avec les colonnes. Ensuite, pour les lignes, c'est aussi facile. D'abord nous remplissons les valeurs nulles avec 0, puis calculons les colonnes des moyennes. val df_filled = df.na.fill ("0"); val nrow = n; val sumDF = df_filled.withColumn ("TOTAL", df_filled.columns.map (c => col (c)). Reduce ((c1, c2) => (c1 + c2)/nrow)); sumDF.show() –

+0

Salut, oui ça va marcher mais encore une fois comme je l'ai dit; si nous remplissons les NA avec des zéros, cela affectera le dénominateur rendant les moyennes calculées biaisées, si je suppose que c'est ainsi que cela sera calculé. Et comme dans mon cas, j'aurai environ 1500 colonnes que je veux additionner, ce qui rend tout à fait impossible de dire quelles colonnes additionner avec une déclaration de réduction. Donc, en conclusion, je dois additionner des lignes et calculer des moyennes où les NA ne prennent pas en compte un grand nombre de colonnes. Chose simple, mais en même temps pas .. – Chooan

0

Vous pouvez le faire en identifiant d'abord quels champs sont numériques, puis en sélectionnant leur moyenne pour chaque ligne ...

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

val df = List(("a",1,2,3.0),("b",5,6,7.0)).toDF("s1","i1","i2","i3") 

// grab numeric fields 
val numericFields = df.schema.fields.filter(f => f.dataType==IntegerType || f.dataType==LongType || f.dataType==FloatType || f.dataType==DoubleType || f.dataType==ShortType).map(_.name) 

// compute mean 
val rowMeans = df.select(numericFields.map(f => col(f)).reduce(_+_)/lit(numericFields.length) as "row_mean") 

rowMeans.show