Объединение фреймов данных на основе двух столбцов и предложения where

#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() в другом месте, у вас могут возникнуть некоторые проблемы.