[PYTHON] Hinweise und Tipps zum vertikalen Verbinden von PySpark DataFrame

Einführung

Zur Erinnerung, es gibt einen überraschend unbekannten Punkt bezüglich der vertikalen Verbindung von PySparks DataFrame.

Der Inhalt des Artikels basiert auf Spark 2.4.

Vertikale Verbindung von PySpark

Über den Unterschied zwischen vertikal verbundenen Methoden

Es gibt drei Arten von vertikalen Verbindungsmethoden für DataFrame.

Unterschied zwischen Vereinigung und Vereinigung Alle

Es gibt tatsächlich keinen induktiven Unterschied zwischen den beiden Methoden uniont und unionAll, die beide einfach vertikal zwei DataFrames verbinden.

Wenn Sie sich SQL vorstellen, ist es leicht zu missverstehen, dass die Duplizierungskontrolle in Union durchgeführt wird, aber in beiden Fällen wird keine Duplizierungskontrolle durchgeführt. Wenn eine doppelte Kontrolle erforderlich ist, muss daher nach der vertikalen Kopplung die Dinstinct-Methode verwendet werden.

In Version 2.0 und höher wird die Verwendung von Union empfohlen.

Union und UnionAll


df1 = spark.createDataFrame([(1, 2, 3), (4, 5, 6)], ['x', 'y', 'z'])
df2 = spark.createDataFrame([(4, 5, 6), (7, 8, 9)], ['x', 'y', 'z'])

df_union = df1.union(df2)
df_unionAll = df1.unionAll(df2)

print('df1')
df1.show()
print('df2')
df2.show()

# df1
# +---+---+---+
# |  x|  y|  z|
# +---+---+---+
# |  1|  2|  3|
# |  4|  5|  6|
# +---+---+---+
#
# df2
# +---+---+---+
# |  x|  y|  z|
# +---+---+---+
# |  4|  5|  6|
# |  7|  8|  9|
# +---+---+---+

print('union')
df_union.show()
print('unionAll')
df_unionAll.show()

# union
# +---+---+---+
# |  x|  y|  z|
# +---+---+---+
# |  1|  2|  3|
# |  4|  5|  6|
# |  4|  5|  6|
# |  7|  8|  9|
# +---+---+---+
#
# unionAll
# +---+---+---+
# |  x|  y|  z|
# +---+---+---+
# |  1|  2|  3|
# |  4|  5|  6|
# |  4|  5|  6|
# |  7|  8|  9|
# +---+---+---+

Unterschied zwischen union und unionByName

Der Unterschied zwischen union und unionByName besteht darin, dass es sich beim vertikalen Verbinden auf den Spaltennamen des DataFrame bezieht.

union verbindet die ersten Spalten von zwei DataFrames, verbindet die zweiten Spalten usw. unter Berücksichtigung der Anordnung der Spalten im DataFrame. Mit anderen Worten, im Fall der Vereinigung wird der Spaltenname zum Zeitpunkt des Beitritts nicht angezeigt. Selbst wenn die DataFrames dieselben Spalten haben und die Reihenfolge unterschiedlich ist, werden sie basierend auf dem Spaltennamen des DataFrames, der die Methode aufgerufen hat, kombiniert, und diejenigen in derselben Spalte werden nicht kombiniert. Andererseits bezieht sich unionByName auf die Spaltennamen jedes DataFrame und verknüpft dieselben Spaltennamen.

Wenn die beiden zu kombinierenden DataFrames dasselbe Schema haben, ist es daher sicher, unionByName zu verwenden.

union und unionByName


df1 = spark.createDataFrame([(1, 2, 3)], ['x', 'y', 'z'])
df2 = spark.createDataFrame([(4, 5, 6)], ['z', 'x', 'y'])

df_union = df1.union(df2)
df_unionByName = df1.unionByName(df2)

print('df1')
df1.show()
print('df2')
df2.show()

# df1
# +---+---+---+
# |  x|  y|  z|
# +---+---+---+
# |  1|  2|  3|
# +---+---+---+
#
# df2
# +---+---+---+
# |  z|  x|  y|
# +---+---+---+
# |  4|  5|  6|
# +---+---+---+

print('union')
df_union.show()
print('unionByName')
df_unionByName.show()

# union
# +---+---+---+
# |  x|  y|  z|
# +---+---+---+
# |  1|  2|  3|
# |  4|  5|  6|
# +---+---+---+
#
# unionByName
# +---+---+---+
# |  x|  y|  z|
# +---+---+---+
# |  1|  2|  3|
# |  5|  6|  4|
# +---+---+---+

Über Cast zum Zeitpunkt des Beitritts

Wenn beim vertikalen Verbinden von DataFrames die zu verbindenden Spaltentypen unterschiedlich sind, kann dies implizit umgewandelt werden. (Einige Muster verursachen einen Fehler, ohne dass dies getan wird.)

Selbst in der impliziten Umwandlung ist das Muster, in dem ein numerischer Typ wie Integer in einen String konvertiert wird, besonders problematisch, und es sollte beachtet werden, dass dies aufgrund von Unterschieden in der Behandlung von Flag-Werten ausreichend auftreten kann.

Hier wird das Beispiel der Vereinigung gezeigt, aber das gleiche gilt für unionByName (ich erkenne empirisch).

Zum Zeitpunkt der vertikalen Verbindung gegossen


from pyspark.sql.functions import col
from pyspark.sql.types import *

df = spark.createDataFrame([(1, 'x', True)], ['long', 'str', 'bool']).withColumn('int', col('long').cast('int'))

df.show()
df.printSchema()

# +------+---+----+---+
# |bigint|str|bool|int|
# +------+---+----+---+
# |     1|  x|true|  1|
# +------+---+----+---+

# root
#  |-- bigint: long (nullable = true)
#  |-- str: string (nullable = true)
#  |-- bool: boolean (nullable = true)
#  |-- int: integer (nullable = true)

df.select('int').union(df.select('str')).printSchema()

# root
#  |-- int: string (nullable = true)

df.select('int').union(df.select('long')).printSchema()

# root
# |-- int: long (nullable = true)

#Dies führt zu einem Fehler
# df.select('bool').union(df.select('str'))

Informationen zur vertikalen Verbindung mehrerer DataFrames

Vertikal verbundene Methoden können nur das Verbinden von zwei DataFrames unterstützen. Wenn Sie 3 oder mehr DataFrames kombinieren möchten, können Sie Folgendes tun.

Vertikale Kombination mehrerer DataFrames


from functools import reduce
from pyspark.sql import DataFrame

df1 = spark.createDataFrame([(1, 2, 3)], ['x', 'y', 'z'])
df2 = spark.createDataFrame([(4, 5, 6)], ['x', 'y', 'z'])
df3 = spark.createDataFrame([(7, 8, 9)], ['x', 'y', 'z'])

df = reduce(DataFrame.unionByName, [df1, df2, df3])
df.show()

# +---+---+---+
# |  x|  y|  z|
# +---+---+---+
# |  1|  2|  3|
# |  4|  5|  6|
# |  7|  8|  9|
# +---+---+---+

Recommended Posts

Hinweise und Tipps zum vertikalen Verbinden von PySpark DataFrame
Hinweise zur Funktion und Rückverfolgung
Anmerkungen zu * args und ** kargs
Anmerkungen zu Pyenv und Atom
Einführung und Tipps von mlflow.Tracking
Hinweise zu Python- und Wörterbuchtypen
Hinweise zur Verwendung von Post-Receive und Post-Merge
Hinweise zur Standardeingabe / -ausgabe von Go
Hinweise zum Erstellen von Python und Pyenv auf dem Mac
Füllen Sie den fehlenden Wert (null) von DataFrame mit den Werten davor und danach mit pyspark
Hinweise zur Installation von Python3 und zur Verwendung von pip unter Windows7
Grundlegende Bedienung von Python Pandas Series und Dataframe (1)