#pandas
#pandas
Вопрос:
Я пытаюсь имитировать условное ЛЕВОЕ ВНЕШНЕЕ соединение SQL в pandas следующим образом:
SELECT sha256_cpn
, rank
FROM cr_df
LEFT JOIN be_df
ON cr_df.sha256_cpn = be_df.sha256_cpn
AND rank = 1
В более общих чертах, у меня есть соединение «многие ко многим» с несколькими записями sha256_cpn in cr_df
и multiple in be_df
, и я хочу присоединить be_df
записи только к первой rank
записи, но сохранить остальные записи в основной таблице. Возможно ли это?
Пример записей в cr_df
:
sha256_cpn | rank | etc. columns
1005a9eaf26b44bfd70b6430f1e86fd14add9b042d4383b6f6fcb6549e5360cb | 1 | ...
1005a9eaf26b44bfd70b6430f1e86fd14add9b042d4383b6f6fcb6549e5360cb | 2 | ...
1005a9eaf26b44bfd70b6430f1e86fd14add9b042d4383b6f6fcb6549e5360cb | 3 | ...
Вот мой код:
// sha256_cpn Object
// rank Integer
cr_df[cr_df['rank']==1].merge(be_df, how='left', on=['sha256_cpn'])
Который выполняет объединение, но, очевидно, отфильтровывает те записи с rank
‘s, которые больше 1
Ответ №1:
Если я правильно понимаю, у вас все в порядке с созданным вами слиянием, но некоторые строки отсутствуют для правильного результата.
Итак, я бы сказал, что вы можете создать свой результат, добавив недостающие строки.
cr_df[cr_df['rank']==1].merge(be_df, how='left', on=['sha256_cpn']).append(cr_df[cr_df['rank']!=1])
Чтобы сделать его еще более общим, вы можете определить a rule
как переменную.
rule = cr_df['rank']==1
cr_df[rule].merge(be_df, how='left', on=['sha256_cpn']).append(cr_df[~rule])
Комментарии:
1. Это сработало именно так, как я хотел. Спасибо!
Ответ №2:
Дублируйте основной фрейм данных перед его объединением.
cr_df1 = cr_df
И после слияния используйте дублированный фрейм данных для фильтрации рангов, отличных от 1.
cr_df1 = cr_df1[cr_df1['rank']!=1]
Комментарии:
1. Вы должны быть осторожны с тем, как вы делаете копию. Чтобы убедиться, что у вас есть копия, а не указатель на переменную, которую вы должны написать
cr_df.copy()
в другом месте, у вас могут возникнуть некоторые проблемы.