web-dev-qa-db-fra.com

Extraire les informations d'un `org.Apache.spark.sql.Row`

J'ai Array[org.Apache.spark.sql.Row] renvoyé par sqc.sql(sqlcmd).collect():

Array([10479,6,10], [8975,149,640], ...)

Je peux obtenir les valeurs individuelles:

scala> pixels(0)(0)
res34: Any = 10479

mais ils sont Any, pas Int.

Comment puis-je les extraire comme Int?

La solution la plus évidente n'a pas fonctionné:

scala> pixels(0).getInt(0)
Java.lang.ClassCastException: Java.lang.String cannot be cast to Java.lang.Int

PS. Je peux faire pixels(0)(0).toString.toInt ou pixels(0).getString(0).toInt mais ils se sentent mal.

15
sds

Utiliser getInt devrait fonctionner. Voici un exemple artificiel comme preuve de concept

import org.Apache.spark.sql._
sc.parallelize(Array(1,2,3)).map(Row(_)).collect()(0).getInt(0)

Ce retour 1

Cependant, 

sc.parallelize(Array("1","2","3")).map(Row(_)).collect()(0).getInt(0)

échoue. On dirait donc qu’il s’agit d’une chaîne et que vous devrez convertir manuellement un int.

sc.parallelize(Array("1","2","3")).map(Row(_)).collect()(0).getString(0).toInt

La documentation indique que getInt:

Renvoie la valeur de la colonne i en tant qu'int. Cette fonction lève une exception si la valeur est at i n'est pas un entier, ou si elle est nulle.

Donc, il ne va pas essayer de lancer pour vous, il semble

11
Justin Pihony

La classe Row (voir aussi https://spark.Apache.org/docs/1.1.0/api/scala/index.html#org.Apache.spark.sql.package ) a des méthodes getInt(i: Int), getDouble(i: Int) etc.

Notez également que SchemaRDD est un RDD[Row]plus un schema qui vous indique quelle colonne a quel type de données. Si vous faites .collect(), vous obtiendrez seulement un Array[Row] qui not n'a pas cette information. Par conséquent, à moins que vous ne sachiez exactement à quoi ressemblent vos données, obtenez le schéma à partir de la variable SchemaRDD, puis collectez les lignes, puis accédez à chaque champ à l'aide des informations de type correctes.

2
tgpfeiffer

la réponse est pertinente. vous n'avez pas besoin d'utiliser collect, vous devez plutôt appeler les méthodes getIntgetString et getAs ainsi si le type de données est complexe

val popularHashTags = sqlContext.sql("SELECT hashtags, usersMentioned, Url FROM tweets")
var hashTagsList =  popularHashTags.flatMap ( x => x.getAs[Seq[String]](0)) 
0
Pankaj Narang