Написать столбец на основе соединения DataFrame - PullRequest
0 голосов
/ 03 июня 2018

Допустим, у меня есть два кадра данных - df1 и df2 - оба с колонками foo и bar.Столбец foo - это хеш-значение CRC32, например 123456, столбец bar - логическое поле со значением по умолчанию False.

В pyspark - эффективный способ сравнения значенийfoo через два DataFrames, записывая столбец bar в True в случае, если они не совпадают.

например, учитывая следующие два DataFrames:

# df1
foo    | bar
-------|------
123456 | False
444555 | False
666777 | False
888999 | False

# df2
foo    | bar
-------|------
938894 | False
129803 | False
666777 | False
888999 | False

Мне нравится новый DataFrame, похожий на следующий, с двумя True столбцами, в которых изменились их хэши:

# df3
foo    | bar
-------|------
938894 | True <---
129803 | True <---
666777 | False
888999 | False

Любое руководство будет высоко оценено.

ОБНОВЛЕНИЕ 7/1/2018

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

В моемВ этом случае у меня были значения хеш-функции CRC32, основанные на пустой строке, что в результате дает 0 для хэша.Я также должен был добавить, что у меня есть уникальная строка, соответствующая строкам, под id здесь (может быть упрощенная ситуация), и, возможно, это то, что нужно присоединить к :

Это создаст такие ситуации:

# df1
id   |foo    | bar
-----|-------|------
abc  |123456 | False
def  |444555 | False
ghi  |0      | False
jkl  |0      | False

# df2
id   |foo    | bar
-----|-------|------
abc  |123456 | False
def  |999999 | False
ghi  |666777 | False
jkl  |0      | False

И с выбранным ответом получит DataFrame с больше строк, чем нужно:

# df3
id   |foo    | bar
-----|-------|------
abc  |123456 | False
def  |999999 | True <---
ghi  |0      | False
jkl  |0      | False
jkl  |0      | False # extra row add through join

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

ДРУГОЕ ОБНОВЛЕНИЕ 1/1/2018, АЛЬТЕРНАТИРОВАТЬ ОТВЕТ

Я слишком усложнил проблему, не указав столбец id.При использовании этого довольно просто присоединиться и написать столбец transformed на основе прямого сравнения столбца fingerprint:

df2.alias("df2").join(df1.alias("df1"), df1.id == df2.id, 'left')\
    .select(f.col('df2.foo'), f.when(df1.fingerprint != df2.fingerprint, f.lit(True)).otherwise(f.col('df2.bar')).alias('bar'))\
    .show(truncate=False)

Ответы [ 2 ]

0 голосов
/ 03 июня 2018

A объединенное левое соединение из df2 с df1 и использование функции when для проверки несоответствующей логики должно дать вам желаемый результат

df2.alias("df2").join(df1.alias("df1"), df1.foo == df2.foo, 'left')\
    .select(f.col('df2.foo'), f.when(f.isnull(f.col('df1.foo')), f.lit(True)).otherwise(f.col('df2.bar')).alias('bar'))\
    .show(truncate=False)

, что должно дать вам

+------+-----+
|foo   |bar  |
+------+-----+
|129803|true |
|938894|true |
|888999|false|
|666777|false|
+------+-----+
0 голосов
/ 03 июня 2018

Я бы предложил использовать левое соединение и написать код так, чтобы при нулевых данных вы выводили false и наоборот.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...