Extraire les valeurs de colonne de Dataframe en tant que liste dans Apache Spark

Je voudrais convertir une colonne de chaîne d'un dataframe en une liste. Ce que je peux trouver à partir de l'API Dataframe est RDD, j'ai donc essayé de le convertir en RDD en premier, puis d'appliquer la fonction toArray au RDD. Dans ce cas, la longueur et le SQL fonctionnent très bien. Cependant, le résultat que J'ai obtenu de RDD a des crochets autour de chaque élément comme celui-ci [A00001]. Je me demandais s'il y avait un moyen approprié de convertir une colonne en une liste ou un moyen de supprimer les crochets.

Toutes les suggestions seraient apprécier. Merci!!!!

53
demandé sur mrsrinivas 2015-08-14 03:39:30

5 réponses

Cela devrait renvoyer la collection contenant une seule liste:

dataFrame.select("YOUR_COLUMN_NAME").rdd.map(r => r(0)).collect()

Sans le mappage, vous obtenez simplement un objet Row, qui contient chaque colonne de la base de données.

Gardez à l'esprit que cela vous donnera probablement une liste de tout type. Ïsi vous voulez spécifier le type de résultat, vous pouvez utiliser .asInstanceOf[YOUR_TYPE] dans r => r(0).asInstanceOf[YOUR_TYPE] mapping

P.S. en raison de la conversion automatique, vous pouvez ignorer la partie .rdd.

75
répondu Niemand 2016-08-25 06:28:26

Avec Spark 2.x et Scala 2.11

Je pense à 3 façons possibles de convertir les valeurs d'une colonne spécifique en List

Extraits de code communs pour toutes les approches

import org.apache.spark.sql.SparkSession

val spark = SparkSession.builder.getOrCreate    
import spark.implicits._ // for .toDf() method

val df = Seq(
    ("first", 2.0),
    ("test", 1.5),
    ("choose", 8.0)
  ).toDF("id", "val")

Approche 1

df.select("id").collect().map(_(0)).toList
// res9: List[Any] = List(one, two, three)

Que se passe-t-il maintenant? Nous collectons des données au pilote avec collect() et sélectionnons l'élément zéro de chaque enregistrement.

cela ne pourrait pas être une excellente façon de le faire, améliorons-le avec la prochaine approche.


Approche 2

df.select("id").rdd.map(r => r(0)).collect.toList 
//res10: List[Any] = List(one, two, three)

Comment est-ce mieux? Nous avons distribué la charge de transformation de carte entre les travailleurs plutôt que le conducteur unique.

je sais rdd.map(r => r(0)) ne semble pas élégant vous. Alors, abordons-le dans la prochaine approche.


Approche 3

df.select("id").map(r => r.getString(0)).collect.toList 
//res11: List[String] = List(one, two, three)

Ici, nous ne convertissons pas DataFrame en RDD. Regardez map il n'acceptera pas r => r(0) (ou _(0)) comme approche précédente en raison de problèmes d'encodeur dans DataFrame. Donc, finissez par utiliser r => r.getString(0) et il serait abordé dans next versions de Spark.

Conclusion

Toutes les options donnent la même sortie mais 2 et 3 sont efficaces, enfin la 3ème est efficace et élégante (je pense).

Databricks cahier de liaison qui sera disponible jusqu'à 6 mois à partir de 2017/05/20

27
répondu mrsrinivas 2017-08-14 05:44:43

Je sais que la réponse donnée et demandée est supposée pour Scala, donc je fournis juste un petit extrait de code Python au cas où un utilisateur de PySpark serait curieux. La syntaxe est similaire à la réponse donnée, mais pour faire apparaître correctement la liste, je dois référencer le nom de la colonne une deuxième fois dans la fonction de mappage et je n'ai pas besoin de l'instruction select.

C'est-à-dire un DataFrame contenant une colonne nommée " Raw "

Pour obtenir chaque valeur de ligne dans" Raw " combiné comme une liste où chaque entrée est une valeur de ligne de " Raw " j'utilise simplement:

MyDataFrame.rdd.map(lambda x: x.Raw).collect()
10
répondu abby sobh 2016-09-30 23:41:23

Dans Scala et Spark 2+, Essayez ceci (en supposant que le nom de votre colonne est " s"): df.select('s).as[String].collect

3
répondu kanielc 2017-07-10 17:20:14
     sqlContext.sql(" select filename from tempTable").rdd.map(r => r(0)).collect.toList.foreach(out_streamfn.println) //remove brackets

Cela fonctionne parfaitement

0
répondu Shaina Raza 2017-12-16 05:58:49