Сравните два набора данных в pyspark - PullRequest
0 голосов
/ 12 февраля 2020

У меня есть 2 набора данных.

Пример набора данных 1:

id     |   model |   first_name   |      last_name
-----------------------------------------------------------
1234   |   32    |    456765      |   [456700,987565]
-----------------------------------------------------------
4539   |   20    |    123211      |   [893456,123456]
-----------------------------------------------------------

Иногда один из столбцов first_name и last_name пуст.

Пример набора данных 2:

number  |  matricule   | name       |    model
----------------------------------------------------------
AA      |  0009        |  456765    |     32
----------------------------------------------------------
AA      |  0009        |  893456    |     32
----------------------------------------------------------
AA      |  0009        |  456700    |     32
----------------------------------------------------------
AA      |  0008        |  456700    |     32
----------------------------------------------------------
AA      |  0008        |  987565    |     32

Для одного matricule мы можем найти больше name и model, как в моем примере чуть выше. Что я должен сделать:

Для каждой строки из набора данных 1, я беру 3 столбца: модель, имя_символа и фамилия и ищу их в наборе данных 2, если они существуют / совпадают в соответствии с элементами matricule.

Я должен сравнить:

  • модель по модели ==> если модель (набор данных 1) существует в модели (набор данных 2) ==> соответствует

  • если first_name существует в name ==> нет совпадений. Если first_name не существует в name ==> match

  • , если last_name существует в name ==> match. Когда у меня есть два значения last_name, оба должны существовать в имени набора данных 2 для сопоставления.

Пример:

Строки 1 из набора данных 1:

id     |   model |   first_name   |      last_name
------------------------------------------------------
1234   |   32    |    456765      |   [456700,987565]

Для matricule 0009 в наборе данных 2 у меня есть:

number  |  matricule   | name       |    model
----------------------------------------------------------
AA      |  0009        |  456765    |     32
----------------------------------------------------------
AA      |  0009        |  893456    |     32
----------------------------------------------------------
AA      |  0009        |  456700    |     32

Итак:

first_name (456765) существует в имени набора данных 2, когда matriule = 0009 = => нет соответствия

last_name, существует только 456700 ==> нет соответствия

модель (32) существует в модели набора данных 2 ==> соответствует

Итак, я пропустите матрицу 0009. И перейдите к сравнению второй строки в наборе данных 1 с элементами матрицы 0008.

Для матрицы 0008 в наборе данных 2 у меня есть:

----------------------------------------------------------
AA      |  0008        |  456700    |     32
----------------------------------------------------------
AA      |  0008        |  987565    |     32

Всегда находимся в первые строки набора данных 1:

first_name (456765) не существует в имени набора данных 2, когда matricule = 0008 ==> match

last_name, оба значения существуют в имени набора данных 2, когда matricule = 0008, ==> соответствует

модель существует в модели набора данных 2, когда matricule = 0008 ==> соответствует

Wh Common crawl ru Я нахожу все совпадения, я создаю новый набор данных, содержащий:

number | id     |  matricule
-----------------------------------
AA     | 1234   | 0008
-----------------------------------

Я надеюсь, что я был чист. Кто-нибудь может помочь мне, пожалуйста.

1 Ответ

1 голос
/ 12 февраля 2020

Вы можете использовать объединение на условиях соответствия.

Сначала вы можете сгруппировать по второму кадру данных и собрать столбец name в список:

df2 = df2.groupBy("number", "model", "matricule").agg(collect_list("name").alias("names"))
f2.show(truncate=False)

#+------+-----+---------+------------------------+
#|number|model|matricule|names                   |
#+------+-----+---------+------------------------+
#|AA    |32   |0009     |[456765, 893456, 456700]|
#|AA    |32   |0008     |[456700, 987565]        |
#+------+-----+---------+------------------------+

Теперь присоединитесь к df1 и df2. Для условий 1 и 2 это как-то просто проверить. Для третьего вы можете использовать array_except, доступный из Spark 2.4+ (не должно быть элементов из столбца last_name, которые не находятся в names и наоборот):

join_condition = (col("df1.model") == col("df2.model")) \
                 & ~expr("array_contains(df2.names, df1.first_name)") \
                 & (size(expr("array_except(df2.names, df1.last_name)")) == lit(0)) \
                 & (size(expr("array_except(df1.last_name, df2.names)")) == lit(0))


df_result = df1.alias("df1").join(df2.alias("df2"), join_condition)

Наконец, выберите нужные столбцы из результата объединения:

df_result.select("number", "id", "matricule").show(truncate=False)

#+------+----+---------+
#|number|id  |matricule|
#+------+----+---------+
#|AA    |1234|0008     |
#+------+----+---------+
...