J'essaie d'imprimer le contenu d'une collection sur la console Spark.
J'ai un type:
linesWithSessionId: org.Apache.spark.rdd.RDD[String] = FilteredRDD[3]
Et j'utilise la commande:
scala> linesWithSessionId.map(line => println(line))
Mais ceci est imprimé:
res1: org.Apache.spark.rdd.RDD [Unité] = MappedRDD [4] sur la carte à: 19
Comment puis-je écrire le RDD sur la console ou le sauvegarder sur le disque afin de pouvoir voir son contenu?
Si vous souhaitez afficher le contenu d'un RDD, vous pouvez utiliser collect()
:
myRDD.collect().foreach(println)
Ce n'est pas une bonne idée, cependant, quand le RDD a des milliards de lignes. Utilisez take()
pour n'en prendre que quelques-uns à imprimer:
myRDD.take(n).foreach(println)
La fonction map
est une transformation , ce qui signifie que Spark n'évaluera pas réellement votre RDD jusqu’à ce que vous exécutiez une action .
Pour l'imprimer, vous pouvez utiliser foreach
(qui est une action):
linesWithSessionId.foreach(println)
Pour l'écrire sur le disque, vous pouvez utiliser l'une des fonctions saveAs...
(actions fixes) de la API RDD
Si vous exécutez ceci sur un cluster, alors println
ne reviendra pas dans votre contexte. Vous devez apporter les données RDD
à votre session. Pour ce faire, vous pouvez le forcer sur un tableau local, puis l’imprimer:
linesWithSessionId.toArray().foreach(line => println(line))
Vous pouvez convertir votre RDD
en un DataFrame
puis show()
-le.
// For implicit conversion from RDD to DataFrame
import spark.implicits._
fruits = sc.parallelize([("Apple", 1), ("banana", 2), ("orange", 17)])
// convert to DF then show it
fruits.toDF().show()
Cela montrera les 20 premières lignes de vos données, de sorte que la taille de vos données ne devrait pas être un problème.
+------+---+
| _1| _2|
+------+---+
| Apple| 1|
|banana| 2|
|orange| 17|
+------+---+
En python
linesWithSessionIdCollect = linesWithSessionId.collect()
linesWithSessionIdCollect
Ceci imprimera tout le contenu du RDD
Il existe probablement de nombreuses différences architecturales entre myRDD.foreach(println)
et myRDD.collect().foreach(println)
(non seulement "collecter", mais également d'autres actions). Une des différences que j'ai vues est que lorsque vous faites myRDD.foreach(println)
, la sortie sera dans un ordre aléatoire. Par exemple: si mon rdd provient d'un fichier texte où chaque ligne a un numéro, la sortie aura un ordre différent. Mais quand j'ai fait myRDD.collect().foreach(println)
, l'ordre reste identique à celui du fichier texte.
Au lieu de taper à chaque fois, vous pouvez:
[1] Créez une méthode d'impression générique dans Spark Shell.
def p(rdd: org.Apache.spark.rdd.RDD[_]) = rdd.foreach(println)
[2] Ou mieux encore, en utilisant implicite, vous pouvez ajouter la fonction à la classe RDD pour imprimer son contenu.
implicit class Printer(rdd: org.Apache.spark.rdd.RDD[_]) {
def print = rdd.foreach(println)
}
Exemple d'utilisation:
val rdd = sc.parallelize(List(1,2,3,4)).map(_*2)
p(rdd) // 1
rdd.print // 2
Sortie:
2
6
4
8
Important
Cela n'a de sens que si vous travaillez en mode local et avec une petite quantité de données. Sinon, vous ne pourrez pas voir les résultats sur le client ou vous manquerez de mémoire en raison du résultat de l'ensemble de données volumineux.
Vous pouvez également enregistrer en tant que fichier: rdd.saveAsTextFile("alicia.txt")
c.take(10)
et Spark version plus récente montrera bien le tableau.