wake-up-neo.net

Extrahieren Sie Spaltenwerte von Dataframe als Liste in Apache Spark

Ich möchte eine Zeichenfolgenspalte eines Datenrahmens in eine Liste konvertieren. Was ich über die Dataframe-API finden kann, ist RDD. Ich habe also erst versucht, sie wieder in RDD zu konvertieren und dann die toArray-Funktion auf die RDD anzuwenden. In diesem Fall funktionieren Länge und SQL einwandfrei. Das Ergebnis, das ich von RDD erhalten habe, hat jedoch eckige Klammern um jedes Element wie diesen [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 werden gebeten. Vielen Dank!

60
SH Y.

Dies sollte die Sammlung mit einer einzelnen Liste zurückgeben:

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

Ohne das Mapping erhalten Sie nur ein Row-Objekt, das jede Spalte aus der Datenbank enthält.

Beachten Sie, dass Sie dadurch wahrscheinlich eine Liste aller Typen erhalten. Wenn Sie den Ergebnistyp angeben möchten, können Sie .asInstanceOf [YOUR_TYPE] im r => r(0).asInstanceOf[YOUR_TYPE]-Mapping verwenden

P.S. Aufgrund der automatischen Konvertierung können Sie den .rdd-Teil überspringen.

81
Niemand

Mit Spark 2.x und Scala 2.11

Ich denke an 3 Möglichkeiten, Werte einer bestimmten Spalte in Liste umzuwandeln

Allgemeine Codeausschnitte 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 an Driver mit collect() und wählen Element aus jedem Datensatz aus. 

Dies könnte keine ausgezeichnete Methode 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 Arbeiter verteilt und nicht auf einen einzelnen Treiber. 

Ich weiß, rdd.map(r => r(0)) scheint dir nicht elegant zu sein. Lasst uns das 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. Sehen Sie sich map an, da r => r(0) (oder _(0)) aufgrund von Encoderproblemen in DataFrame nicht als der vorherige Ansatz akzeptiert wird. Am Ende verwenden Sie r => r.getString(0) und würden in den nächsten Spark-Versionen angesprochen.

Fazit

Alle Optionen haben die gleiche Leistung, aber 2 und 3 sind effektiv, schließlich ist die dritte effektiv und elegant (würde ich denken).

Databricks-Notebook-Link, der ab dem 20.05.2017 bis 6 Monate verfügbar sein wird

34
mrsrinivas

Ich weiß, dass die Antwort für Scala als Antwort auf die Antwort angegeben und gefragt wird. Ich gebe nur einen kleinen Ausschnitt des Python-Codes für den Fall, dass ein PySpark-Benutzer neugierig ist. Die Syntax ähnelt der gegebenen Antwort, aber um die Liste richtig herauszuholen, muss ich tatsächlich den Spaltennamen ein zweites Mal in der Mapping-Funktion referenzieren und brauche die select-Anweisung nicht.

ein DataFrame, der eine Spalte namens "Raw" enthält.

Um jeden Zeilenwert in "Raw" als Liste zusammenzufassen, wobei jeder Eintrag ein Zeilenwert aus "Raw" ist, verwende ich einfach:

MyDataFrame.rdd.map(lambda x: x.Raw).collect()
14
abby sobh

Versuchen Sie Folgendes in Scala und Spark 2+ (vorausgesetzt, Ihr Spaltenname ist "s"): df.select('s).as[String].collect

4
kanielc
     sqlContext.sql(" select filename from tempTable").rdd.map(r => r(0)).collect.toList.foreach(out_streamfn.println) //remove brackets

es funktioniert perfekt

0
Shaina Raza