Коротко
- Ключи называются по-разному —
left_on="customer", right_on="client_id". По индексу —left_index=True/right_index=True. - Одноимённые столбцы, которые не являются ключом, получают суффиксы
_xи_y; свои —suffixes=("_a", "_b"). indicator=Trueдобавляет столбец_merge:both,left_only,right_only— удобно искать строки без пары.validate="one_to_one","one_to_many","many_to_one"проверяет уникальность ключей и падает, если она нарушена.df.join(other)— короткая формаmergeпо индексуother.
Синтаксис
left.merge(right, left_on="a", right_on="b", how="left")
left.merge(right, left_on="a", right_index=True)
left.merge(right, on="k", suffixes=("_x", "_y"), indicator=False, validate=None)
left.join(right, on=None, how="left")Параметры
ПараметрЧто делаетПо умолчанию
left_on / right_onключи с разными именами в левой и правой таблицеNoneleft_index / right_indexиспользовать индекс как ключFalsesuffixesсуффиксы для одноимённых столбцов("_x", "_y")indicatorдобавить столбец _merge с источником строкиFalsevalidate"one_to_one", "one_to_many", "many_to_one", "many_to_many"NoneПримеры
clients = pd.DataFrame({"client_id": [1, 2, 3], "name": ["Аня", "Борис", "Вика"], "city": ["Омск", "Тула", "Сочи"]})
orders = pd.DataFrame({"order": [10, 11, 12], "customer": [2, 3, 4], "city": ["Тула", "Москва", "Омск"]})orders.merge(clients, left_on="customer", right_on="client_id", how="left")Вывод
order customer city_x client_id name city_y 0 10 2 Тула 2.0 Борис Тула 1 11 3 Москва 3.0 Вика Сочи 2 12 4 Омск NaN NaN NaN
orders.merge(clients, left_on="customer", right_on="client_id",
suffixes=("_delivery", "_client"))Вывод
order customer city_delivery client_id name city_client 0 10 2 Тула 2 Борис Тула 1 11 3 Москва 3 Вика Сочи
res = orders.merge(clients, left_on="customer", right_on="client_id", how="outer", indicator=True)
res[["order", "name", "_merge"]]Вывод
order name _merge 0 NaN Аня right_only 1 10.0 Борис both 2 11.0 Вика both 3 12.0 NaN left_only
cl = clients.set_index("client_id")
orders.merge(cl[["name"]], left_on="customer", right_index=True, how="left")Вывод
order customer city name 0 10 2 Тула Борис 1 11 3 Москва Вика 2 12 4 Омск NaN
cl = clients.set_index("client_id")
orders.set_index("customer").join(cl[["name"]], how="left") # join — merge по индексуВывод
order city name customer 2 10 Тула Борис 3 11 Москва Вика 4 12 Омск NaN
plan = pd.DataFrame({"city": ["Омск", "Омск"], "month": ["янв", "фев"], "plan": [100, 120]})
fact = pd.DataFrame({"city": ["Омск", "Омск"], "month": ["фев", "янв"], "fact": [130, 95]})
plan.merge(fact, on=["city", "month"]) # пара ключейВывод
city month plan fact 0 Омск янв 100 95 1 Омск фев 120 130
Подводные камни
Неожиданные дубликаты в справочнике
Повтор в «справочной» таблице молча размножает строки фактов. validate превращает это в явную ошибку.
dup = pd.concat([clients, clients.head(1)]) # клиент 1 записан дважды
orders.merge(dup, left_on="customer", right_on="client_id", validate="many_to_one")Ошибка
MergeError: Merge keys are not unique in right dataset; not a many-to-one merge
Duplicates in right:
client_id
1 ...Два столбца-ключа в результате
С left_on / right_on оба ключа остаются в результате (customer и client_id). Лишний удалите через drop(columns=…).