Слияние левого фрейма данных с совпадающими ключами в разных столбцах

#python #pandas #dataframe #merge

#python #панды #Фрейм данных #слияние

Вопрос:

Я должен объединить два DataFrame , с левым соединением — иллюстрация ниже.

Проблема в том, что совпадающий ключ распределен по 3 столбцам. Чтобы еще больше усложнить задачу, некоторые строки (# 4) будут иметь один и тот же совпадающий ключ дважды! Мне посоветовали использовать Melt , но это работает только для правильного соединения.

Каков наилучший подход?

импортируйте pandas как pd

 data1 = {'key1' : ['abc','aa','aa','sdf'],
         'key2' : ['aa','efg','aa', 'sdf'],
         'key3' : ['aa','aa','xyz', 'aa']
        }

data2 = {'key': ['abc','efg', 'xyz', 'sdf'], 
        'msg' : ['happy','mad','smile','great']}

df1= pd.DataFrame(data1)
df2= pd.DataFrame(data2)
 

введите описание изображения здесь

Ответ №1:

Давайте попробуем stack изменить df1 map форму ключей с соответствующими msg from df2 , наконец groupby , on level=0 и агрегировать с помощью first :

 df1['msg'] = df1.stack().map(df2.set_index('key')['msg']).groupby(level=0).first()
 

   key1 key2 key3    msg
0  abc   aa   aa  happy
1   aa  efg   aa    mad
2   aa   aa  xyz  smile
3  sdf  sdf   aa  great
 

Комментарии:

1. Работает отлично! Могу ли я спросить, есть ли какие-либо ограничения для этого метода?

2. Что делать, если DF1 имеет 3 ключевых, но также и неключевые столбцы. Как я могу применить стек? @shubham-sharma

3. @denpy Это здорово! Я не думаю, что есть какие-либо ограничения, за исключением случаев, когда df2 содержит дубликаты ключей.. Но в этом случае вы можете использовать drop_duplicates , и это будет работать нормально.

4. @denpy В случае, если фрейм данных содержит неключевые столбцы, вы можете просто отфильтровать требуемые key столбцы, используя df1.filter(like='key') перед использованием stack

5. @denpy Счастливого кодирования 🙂

Ответ №2:

Как насчет этого? Вы можете воссоздать временный фрейм данных, в котором все ключи находятся в одних и тех же столбцах, выполнить объединение, затем удалить все дубликаты (и повторно объединить с вашим первым фреймом данных) :

 df1.reset_index(drop=True, inplace=True)

df3 = pd.DataFrame(
  df1[["index", "key1"]].values.tolist()
    df1[["index", "key2"]].values.tolist()
    df1[["index", "key3"]].values.tolist(),
  columns=['index', 'key'])
df4 = df3.merge(df2, on="key", how="left")
df4.sort_values('index', inplace=True)
df4.drop_duplicates('index', keep='first')

df = df1.merge(df4[['index', 'msg']], on="index", how='left')