#apache-spark #pyspark #apache-spark-sql
#apache-spark #pyspark #apache-spark-sql
Вопрос:
У меня есть два фрейма данных в PySpark, и я хотел бы выполнить для них внешнее соединение. Мне нужно иметь возможность присоединять их к именам столбцов, которые различаются в каждой таблице и могут меняться (поэтому должны быть переменными, а не жестко заданными). Однако, когда я делаю это в данный момент, PySpark возвращает фрейм данных, включающий оба столбца, которые объединяются, с некоторыми значениями, заполненными нулями.
Пример кода, который я сейчас использую,:
>>> df1 = spark.createDataFrame([[1,'apple'],[2,'orange']], ['id_fruit','fruit'])
>>> df2 = spark.createDataFrame([[2,100],[3,30]], ['fruit_id','numberInStock'])
>>> df1.show()
-------- ------
|id_fruit| fruit|
-------- ------
| 1| apple|
| 2|orange|
-------- ------
>>> df2.show()
-------- -------------
|fruit_id|numberInStock|
-------- -------------
| 2| 100|
| 3| 30|
-------- -------------
>>> left_join_on = 'id_fruit'
>>> right_join_on = 'fruit_id'
>>> df1.join(df2, df1[left_join_on] == df2[right_join_on], how='outer').show()
-------- ------ -------- -------------
|id_fruit| fruit|fruit_id|numberInStock|
-------- ------ -------- -------------
| 1| apple| null| null|
| null| null| 3| 30|
| 2|orange| 2| 100|
-------- ------ -------- -------------
Как указано выше, сохраняются оба столбца, которые используются для объединения. Для внутренних соединений это было бы хорошо (например, я мог бы просто удалить один из столбцов), но с внешним соединением мне действительно нужны оба значения ID в одном столбце (например, на случай, если я захочу выполнить последующее объединение). В идеале результат, который я хочу, будет выглядеть примерно так:
-------- ------ -------------
|id_fruit| fruit|numberInStock|
-------- ------ -------------
| 1| apple| null|
| 3| null| 30|
| 2|orange| 100|
-------- ------ -------------
только с одним столбцом ID. Кто-нибудь знает, как я мог бы этого добиться?
Ответ №1:
Вы можете coalesce
использовать два столбца:
df1.join(df2, df1[left_join_on] == df2[right_join_on], how='outer')
.select('*', F.coalesce(F.col(left_join_on), F.col(right_join_on)))
.show()
Если вы хотите сохранить только этот объединенный столбец,
df1.join(df2, df1[left_join_on] == df2[right_join_on], how='outer')
.select('*', F.coalesce(F.col(left_join_on), F.col(right_join_on)).alias('coalesced'))
.drop(left_join_on, right_join_on)
.show()