Unir dos marcos de datos, seleccionar todas las columnas de una y algunas columnas de la otra


Digamos que tengo un marco de datos spark df1, con varias columnas (entre las cuales la columna 'id') y un marco de datos df2 con dos columnas, 'id' y 'otro'.

Hay una manera de replicar el siguiente comando

sqlContext.sql("SELECT df1.*, df2.other FROM df1 JOIN df2 ON df1.id = df2.id")

Usando solo funciones pyspark como join(), select() y similares?

Tengo que implementar esta combinación en una función y no quiero que me obliguen a tener SQLContext como parámetro de función.

Gracias!

Author: Francesco Sambo, 2016-03-21

5 answers

No estoy seguro de si la forma más eficiente, pero esto funcionó para mí:

from pyspark.sql.functions import col

df1.alias('a').join(df2.alias('b'),col('b.id') == col('a.id')).select([col('a.'+xx) for xx in a.columns] + [col('b.other1'),col('b.other2')])

El truco está en:

[col('a.'+xx) for xx in a.columns] : all columns in a

[col('b.other1'),col('b.other2')] : some columns of b
 31
Author: Pablo Estevez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-12 10:33:14

Asterisk (*) funciona con alias. Ex:

from pyspark.sql.functions import *

df1 = df.alias('df1')
df2 = df.alias('df2')

df1.join(df2, df1.id == df2.id).select('df1.*')
 28
Author: maxcnunes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-22 11:15:16

Aquí hay una solución que no requiere un contexto SQL, pero mantiene los metadatos de un DataFrame.

a = sc.parallelize([['a', 'foo'], ['b', 'hem'], ['c', 'haw']]).toDF(['a_id', 'extra'])
b = sc.parallelize([['p1', 'a'], ['p2', 'b'], ['p3', 'c']]).toDF(["other", "b_id"])

c = a.join(b, a.a_id == b.b_id)

Entonces, c.show() rinde:

+----+-----+-----+----+
|a_id|extra|other|b_id|
+----+-----+-----+----+
|   a|  foo|   p1|   a|
|   b|  hem|   p2|   b|
|   c|  haw|   p3|   c|
+----+-----+-----+----+
 9
Author: Katya Handler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-21 15:58:23

Simplemente podría hacer la unión y después seleccionar las columnas deseadashttps://spark.apache.org/docs/latest/api/python/pyspark.sql.html?highlight=dataframe%20join#pyspark.sql.DataFrame.join

 0
Author: Erica,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-21 14:03:30

Eliminar duplicados b_id

c = a.join(b, a.a_id == b.b_id).drop(b.b_id)
 0
Author: Selvaraj S.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-31 10:21:29