Как изменить столбец для объединения в фрейме данных spark, если ключ объединения указан в виде списка? - PullRequest
0 голосов
/ 12 февраля 2019

Я пытался объединить два кадра данных, используя следующий список ключей объединения, переданных в виде списка, и я хочу добавить функциональность для объединения на подмножестве ключей, если одно из значений ключа равно нулю

Я пытался объединить два фрейма данных df_1 и df_2.

data1 = [[1,'2018-07-31',215,'a'],
        [2,'2018-07-30',None,'b'],
        [3,'2017-10-28',201,'c']
     ]
df_1 = sqlCtx.createDataFrame(data1, 
['application_number','application_dt','account_id','var1']) 

и

data2 = [[1,'2018-07-31',215,'aaa'],
        [2,'2018-07-30',None,'bbb'],
        [3,'2017-10-28',201,'ccc']
        ]
df_2 = sqlCtx.createDataFrame(data2, 
['application_number','application_dt','account_id','var2'])

Код, который я использую для присоединения, выглядит так:

key_a = ['application_number','application_dt','account_id']
new = df_1.join(df_2,key_a,'left')

Вывод для того же:

+------------------+--------------+----------+----+----+
|application_number|application_dt|account_id|var1|var2|
+------------------+--------------+----------+----+----+
|                 1|    2018-07-31|       215|   a| aaa|
|                 3|    2017-10-28|       201|   c| ccc|
|                 2|    2018-07-30|      null|   b|null|
+------------------+--------------+----------+----+----+

Меня беспокоит то, что в случае, когда account_id имеет значение null, объединение все равно должно работать, сравнивая другие 2 ключа.

Требуемый результат должен быть таким:

+------------------+--------------+----------+----+----+
|application_number|application_dt|account_id|var1|var2|
+------------------+--------------+----------+----+----+
|                 1|    2018-07-31|       215|   a| aaa|
|                 3|    2017-10-28|       201|   c| ccc|
|                 2|    2018-07-30|      null|   b| bbb|
+------------------+--------------+----------+----+----+

Я нашел аналогичный подход для этого, используя выражение:

  join_elem = "df_1.application_number == 
  df_2.application_number|df_1.application_dt == 
  df_2.application_dt|F.coalesce(df_1.account_id,F.lit(0)) ==  
  F.coalesce(df_2.account_id,F.lit(0))".split("|")
  join_elem_column = [eval(x) for x in join_elem]

Но при рассмотрении проектане позволяйте мне использовать полное выражение соединения, и я застрял с использованием списка имен столбцов в качестве ключа соединения.

Я пытался найти способ включить эту объединенную вещь в сам этот список, нопока не добились успеха.

1 Ответ

0 голосов
/ 12 февраля 2019

Я бы назвал это решение обходным путем.

Проблема здесь в том, что у нас есть значение Null для одного из ключей в DataFrame, и ОП хочет, чтобы остальные ключевые столбцы былииспользуется вместоПочему бы не присвоить произвольное значение этому Null, а затем применить соединение.По сути, это было бы то же самое, что объединить оставшиеся два ключа.

# Let's replace Null with an arbitrary value, which has
# little chance of occurring in the Dataset. For eg; -100000
df1 = df1.withColumn('account_id', when(col('account_id').isNull(),-100000).otherwise(col('account_id')))    
df2 = df2.withColumn('account_id', when(col('account_id').isNull(),-100000).otherwise(col('account_id')))

# Do a FULL Join
df = df1.join(df2,['application_number','application_dt','account_id'],'full')

# Replace the arbitrary value back with Null.    
df = df.withColumn('account_id', when(col('account_id')== -100000, None).otherwise(col('account_id')))
df.show()
+------------------+--------------+----------+----+----+
|application_number|application_dt|account_id|var1|var2|
+------------------+--------------+----------+----+----+
|                 1|    2018-07-31|       215|   a| aaa|
|                 2|    2018-07-30|      null|   b| bbb|
|                 3|    2017-10-28|       201|   c| ccc|
+------------------+--------------+----------+----+----+
...