#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')