PySpark: вставьте или обновите фрейм данных с другим фреймом данных - PullRequest
0 голосов
/ 24 августа 2018

У меня есть два кадра данных, DF1 и DF2, DF1 является ведущим, а DF2 является дельтой. Данные из DF2 должны быть вставлены в DF1 или использованы для обновления данных DF1. Объяснение ниже:

Допустим, DF1 имеет следующий формат:

id_no | дата начала | количество | дней
--------------------------------------------
1 | 2016-01-01 | 4650 | 22
2 | 2016-01-02 | 3130 | 45
1 | 2016-01-03 | 4456 | 22
2 | 2016-01-15 | 1234 | 45

DF2 содержит следующее:

id_no | дата начала | количество | дней
--------------------------------------------
1 | 2016-01-01 | 8650 | 52
2 | 2016-01-02 | 7130 | 65
1 | 2016-01-06 | 3456 | 20
2 | 2016-01-20 | 2345 | 19
3 | 2016-02-02 | 1345 | 19

Мне нужно объединить два кадра данных таким образом, чтобы, если «id_no» и «дата начала» DF2 совпадали с DF1, его нужно было заменить в DF1, а если он не совпадает, его нужно вставить в DF1. Id_no не является уникальным.

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

id_no | дата начала | количество | дней
--------------------------------------------
1 | 2016-01-01 | 8650 | 52
2 | 2016-01-02 | 7130 | 65
1 | 2016-01-03 | 4456 | 22
2 | 2016-01-15 | 1234 | 45
1 | 2016-01-06 | 3456 | 20
2 | 2016-01-20 | 2345 | 19
3 | 2016-02-02 | 1345 | 19

Пожалуйста, кто-нибудь может подсказать мне, как к этому подойти.

1 Ответ

0 голосов
/ 24 августа 2018

Вы можете объединить два фрейма данных id_no и start_date, а затем coalesce столбец amount и days со столбцами из df2 после:

import pyspark.sql.functions as f

df1.alias('a').join(
    df2.alias('b'), ['id_no', 'start_date'], how='outer'
).select('id_no', 'start_date', 
    f.coalesce('b.amount', 'a.amount').alias('amount'), 
    f.coalesce('b.days', 'a.days').alias('days')
).show()

+-----+----------+------+----+
|id_no|start_date|amount|days|
+-----+----------+------+----+
|    1|2016-01-06|  3456|  20|
|    2|2016-01-20|  2345|  19|
|    1|2016-01-03|  4456|  22|
|    3|2016-02-02|  1345|  19|
|    2|2016-01-15|  1234|  45|
|    1|2016-01-01|  8650|  52|
|    2|2016-01-02|  7130|  65|
+-----+----------+------+----+

Если у вас есть еще много столбцов:

cols = ['amount', 'days']

df1.alias('a').join(
    df2.alias('b'), ['id_no', 'start_date'], how='outer'
).select('id_no', 'start_date', 
    *(f.coalesce('b.' + col, 'a.' + col).alias(col) for col in cols)
).show()
+-----+----------+------+----+
|id_no|start_date|amount|days|
+-----+----------+------+----+
|    1|2016-01-06|  3456|  20|
|    2|2016-01-20|  2345|  19|
|    1|2016-01-03|  4456|  22|
|    3|2016-02-02|  1345|  19|
|    2|2016-01-15|  1234|  45|
|    1|2016-01-01|  8650|  52|
|    2|2016-01-02|  7130|  65|
+-----+----------+------+----+
...