Ich möchte eine Zeichenfolgenspalte eines Datenrahmens in eine Liste konvertieren. Was ich in der Dataframe
API finden kann, ist RDD. Daher habe ich versucht, es zuerst wieder in RDD zu konvertieren und dann die toArray
Funktion auf das RDD anzuwenden . In diesem Fall funktionieren Länge und SQL einwandfrei. Das Ergebnis von RDD hat jedoch eckige Klammern um jedes Element wie dieses [A00001]
. Ich habe mich gefragt, ob es eine geeignete Möglichkeit gibt, eine Spalte in eine Liste umzuwandeln oder die eckigen Klammern zu entfernen.
Anregungen wäre dankbar. Vielen Dank!
Antworten:
Dies sollte die Sammlung zurückgeben, die eine einzelne Liste enthält:
dataFrame.select("YOUR_COLUMN_NAME").rdd.map(r => r(0)).collect()
Ohne die Zuordnung erhalten Sie nur ein Zeilenobjekt, das jede Spalte aus der Datenbank enthält.
Denken Sie daran, dass Sie dadurch wahrscheinlich eine Liste mit beliebigen Typen erhalten. ÏWenn Sie den Ergebnistyp angeben möchten, können Sie .asInstanceOf [YOUR_TYPE] für die
r => r(0).asInstanceOf[YOUR_TYPE]
Zuordnung verwendenPS Aufgrund der automatischen Konvertierung können Sie das
.rdd
Teil überspringen .quelle
collect().map(r => r(0))
- hat diese Reihenfolge irgendwelche Nachteile?Mit Spark 2.x und Scala 2.11
Ich würde mir 3 Möglichkeiten vorstellen, um Werte einer bestimmten Spalte in List umzuwandeln.
Gemeinsame Codefragmente für alle Ansätze
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")
Ansatz 1
df.select("id").collect().map(_(0)).toList // res9: List[Any] = List(one, two, three)
Was passiert jetzt? Wir sammeln Daten für den Treiber mit
collect()
und wählen aus jedem Datensatz das Element Null aus.Dies könnte keine hervorragende Möglichkeit sein. Verbessern wir es mit dem nächsten Ansatz.
Ansatz 2
df.select("id").rdd.map(r => r(0)).collect.toList //res10: List[Any] = List(one, two, three)
Wie ist es besser Wir haben die Last der Kartentransformation auf die Worker verteilt und nicht auf einen einzelnen Treiber.
Ich weiß,
rdd.map(r => r(0))
scheint dir nicht elegant zu sein. Lassen Sie uns dies im nächsten Ansatz ansprechen.Ansatz 3
df.select("id").map(r => r.getString(0)).collect.toList //res11: List[String] = List(one, two, three)
Hier konvertieren wir DataFrame nicht in RDD. Schauen Sie sich an, dass
map
dies aufgrund von Encoderproblemen in DataFrame nicht als vorheriger Ansatz akzeptiertr => r(0)
(oder_(0)
) wird. Verwendenr => r.getString(0)
Sie also am Ende und es wird in den nächsten Versionen von Spark behandelt.Alle Optionen liefern die gleiche Ausgabe, aber 2 und 3 sind effektiv, schließlich ist die dritte effektiv und elegant (würde ich denken).
Databricks Notizbuch
quelle
Ich weiß, dass die gegebene und angeforderte Antwort für Scala angenommen wird, daher stelle ich nur einen kleinen Ausschnitt aus Python-Code zur Verfügung, falls ein PySpark-Benutzer neugierig ist. Die Syntax ähnelt der angegebenen Antwort, aber um die Liste richtig zu löschen, muss ich in der Zuordnungsfunktion ein zweites Mal auf den Spaltennamen verweisen, und ich benötige die select-Anweisung nicht.
dh ein DataFrame, der eine Spalte mit dem Namen "Raw" enthält
Um jeden Zeilenwert in "Raw" als Liste zu kombinieren, wobei jeder Eintrag ein Zeilenwert aus "Raw" ist, verwende ich einfach:
MyDataFrame.rdd.map(lambda x: x.Raw).collect()
quelle
Versuchen Sie dies in Scala und Spark 2+ (vorausgesetzt, Ihr Spaltenname lautet "s"):
df.select('s).as[String].collect
quelle
sqlContext.sql(" select filename from tempTable").rdd.map(r => r(0)).collect.toList.foreach(out_streamfn.println) //remove brackets
es funktioniert perfekt
quelle
List<String> whatever_list = df.toJavaRDD().map(new Function<Row, String>() { public String call(Row row) { return row.getAs("column_name").toString(); } }).collect(); logger.info(String.format("list is %s",whatever_list)); //verification
Da niemand eine Lösung in Java (Real Programming Language) gegeben hat, kann ich mich später bedanken
quelle
from pyspark.sql.functions import col df.select(col("column_name")).collect()
Hier sammeln ist Funktionen, die es wiederum in Liste konvertieren. Verwenden Sie die Liste für den riesigen Datensatz. Dies verringert die Leistung. Es ist gut, die Daten zu überprüfen.
quelle
Dies ist Java-Antwort.
df.select("id").collectAsList();
quelle
Eine aktualisierte Lösung, mit der Sie eine Liste erhalten:
dataFrame.select("YOUR_COLUMN_NAME").map(r => r.getString(0)).collect.toList
quelle