Остановить pyspark, возвращающий оба «включенных» столбца после объединения

#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()