Pyspark: Split multiple array Spalten in Zeilen
Habe ich ein dataframe, das hat eine Zeile und mehrere Spalten. Einige der Spalten sind die einzelnen Werte, und andere sind Listen. Alle Listen-Spalten die gleiche Länge. Ich möchte split jede Liste Spalte in eine separate Zeile, während alle nicht-Liste Spalte.
Beispiel DF:
df = sqlc.createDataFrame([Row(a=1, b=[1,2,3],c=[7,8,9], d='foo')])
# +---+---------+---------+---+
# | a| b| c| d|
# +---+---------+---------+---+
# | 1|[1, 2, 3]|[7, 8, 9]|foo|
# +---+---------+---------+---+
Was ich will:
+---+---+----+------+
| a| b| c | d |
+---+---+----+------+
| 1| 1| 7 | foo |
| 1| 2| 8 | foo |
| 1| 3| 9 | foo |
+---+---+----+------+
Wenn ich hatte nur eine Liste Spalte, wäre dies einfach, indem Sie einfach tun, eine explode
:
df_exploded = df.withColumn('b', explode('b'))
# >>> df_exploded.show()
# +---+---+---------+---+
# | a| b| c| d|
# +---+---+---------+---+
# | 1| 1|[7, 8, 9]|foo|
# | 1| 2|[7, 8, 9]|foo|
# | 1| 3|[7, 8, 9]|foo|
# +---+---+---------+---+
Jedoch, wenn ich versuche, auch explode
die c
Spalte, Ende ich mit einem dataframe mit einer Länge des Platzes von dem, was ich will:
df_exploded_again = df_exploded.withColumn('c', explode('c'))
# >>> df_exploded_again.show()
# +---+---+---+---+
# | a| b| c| d|
# +---+---+---+---+
# | 1| 1| 7|foo|
# | 1| 1| 8|foo|
# | 1| 1| 9|foo|
# | 1| 2| 7|foo|
# | 1| 2| 8|foo|
# | 1| 2| 9|foo|
# | 1| 3| 7|foo|
# | 1| 3| 8|foo|
# | 1| 3| 9|foo|
# +---+---+---+---+
Was ich will, ist - für jede Spalte, nehmen Sie die N-te element des Arrays in die Spalte und füge eine neue Zeile. Ich habe versucht, die Zuordnung eines explodieren quer durch alle Spalten in der dataframe, aber das scheint nicht zu funktionieren:
df_split = df.rdd.map(lambda col: df.withColumn(col, explode(col))).toDF()
InformationsquelleAutor der Frage Steve | 2016-12-07
Du musst angemeldet sein, um einen Kommentar abzugeben.
Funke >= 2.4
Können Sie ersetzen
zip_
udf
mitarrays_zip
FunktionFunke < 2.4
Mit
DataFrames
und UDF:Mit
RDDs
:Beide Lösungen sind ineffizient aufgrund Python Kommunikations-overhead. Wenn die Größe der Daten behoben wird, können Sie etwas wie das hier tun:
oder auch:
Diese sollten deutlich schneller im Vergleich zu UDF oder RDD. Verallgemeinert auf eine beliebige Anzahl von Spalten:
InformationsquelleAutor der Antwort user6910411
Würden Sie verwenden müssen
flatMap
nichtmap
wie Sie wollen-multiple-output-Zeilen aus jeder Eingabezeile.InformationsquelleAutor der Antwort David