Pandas Merge: O guia completo para mesclar DataFrames em Python
Updated on
Trabalhar com um único DataFrame é raro no mundo real. A maioria dos projetos de análise de dados requer que você combine dados de múltiplas fontes -- registros de vendas com perfis de clientes, leituras de sensores com metadados de dispositivos, ou respostas de pesquisas com tabelas demográficas. A função pandas merge é a ferramenta padrão que os desenvolvedores Python usam para unir DataFrames, e compreendê-la bem é a diferença entre gastar minutos ou horas na preparação de dados.
Este guia cobre todos os aspectos do pd.merge(): os quatro tipos principais de junção, mesclagem em várias colunas, tratamento de nomes duplicados e armadilhas comuns. Cada exemplo usa código funcional que você pode copiar diretamente para o seu notebook.
O que pd.merge() faz
pd.merge() combina dois DataFrames combinando linhas com base em uma ou mais colunas compartilhadas (chamadas chaves). Funciona como uma instrução SQL JOIN. Você escolhe em quais colunas combinar e que tipo de junção realizar, e o pandas cuida do resto.
Aqui está a sintaxe básica:
import pandas as pd
result = pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None,
suffixes=('_x', '_y'), indicator=False, validate=None)Referência de parâmetros principais
| Parâmetro | Descrição | Padrão |
|---|---|---|
left | O primeiro DataFrame (esquerdo) | Obrigatório |
right | O segundo DataFrame (direito) | Obrigatório |
how | Tipo de junção: 'inner', 'left', 'right', 'outer', 'cross' | 'inner' |
on | Nome(s) de coluna para junção (deve existir em ambos os DataFrames) | None |
left_on | Coluna(s) do DataFrame esquerdo para usar como chaves | None |
right_on | Coluna(s) do DataFrame direito para usar como chaves | None |
left_index | Usar o índice do DataFrame esquerdo como chave de junção | False |
right_index | Usar o índice do DataFrame direito como chave de junção | False |
suffixes | Sufixos para aplicar a nomes de colunas sobrepostas | ('_x', '_y') |
indicator | Adicionar uma coluna mostrando a origem de cada linha | False |
validate | Verificar se a mesclagem é um-para-um, um-para-muitos, etc. | None |
Se você omitir on, left_on e right_on, o pandas unirá automaticamente todas as colunas que compartilham o mesmo nome em ambos os DataFrames.
Dados de exemplo para todos os exemplos
Cada exemplo abaixo usa esses dois DataFrames:
import pandas as pd
employees = pd.DataFrame({
'emp_id': [1, 2, 3, 4, 5],
'name': ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'],
'dept_id': [10, 20, 10, 30, 20]
})
departments = pd.DataFrame({
'dept_id': [10, 20, 40],
'dept_name': ['Engineering', 'Marketing', 'Sales']
})
print(employees)
print(departments)Saída:
emp_id name dept_id
0 1 Alice 10
1 2 Bob 20
2 3 Charlie 10
3 4 Diana 30
4 5 Eve 20
dept_id dept_name
0 10 Engineering
1 20 Marketing
2 40 SalesObserve que dept_id 30 existe apenas em employees, e dept_id 40 existe apenas em departments. Essa incompatibilidade é intencional -- ela torna a diferença entre os tipos de junção óbvia.
Inner Merge (padrão)
Um inner merge retorna apenas as linhas onde a chave existe em ambos os DataFrames. Linhas sem correspondência são descartadas.
inner_result = pd.merge(employees, departments, on='dept_id', how='inner')
print(inner_result)Saída:
emp_id name dept_id dept_name
0 1 Alice 10 Engineering
1 3 Charlie 10 Engineering
2 2 Bob 20 Marketing
3 5 Eve 20 MarketingDiana (dept_id=30) é descartada porque o departamento 30 não existe na tabela departments. O departamento 40 (Vendas) também está ausente porque nenhum funcionário pertence a ele.
Quando usar inner merge: Use quando você quiser apenas registros completos -- linhas que tenham dados válidos em ambos os lados. Este é o padrão mais seguro porque nunca introduz valores NaN de linhas não correspondidas.
Left Merge
Um left merge mantém todas as linhas do DataFrame esquerdo e apenas as linhas correspondentes da direita. Onde não há correspondência, as colunas do lado direito são preenchidas com NaN.
left_result = pd.merge(employees, departments, on='dept_id', how='left')
print(left_result)Saída:
emp_id name dept_id dept_name
0 1 Alice 10 Engineering
1 2 Bob 20 Marketing
2 3 Charlie 10 Engineering
3 4 Diana 30 NaN
4 5 Eve 20 MarketingDiana agora está incluída, mas seu dept_name é NaN porque o departamento 30 não tem entrada na tabela departments.
Quando usar left merge: Use quando o DataFrame esquerdo for seu conjunto de dados "primário" e você quiser enriquecê-lo com colunas adicionais, sem perder nenhuma linha da tabela primária. Este é o tipo de merge mais comum na prática.
Right Merge
Um right merge é o espelho de um left merge. Ele mantém todas as linhas do DataFrame direito e apenas linhas correspondentes da esquerda.
right_result = pd.merge(employees, departments, on='dept_id', how='right')
print(right_result)Saída:
emp_id name dept_id dept_name
0 1.0 Alice 10 Engineering
1 3.0 Charlie 10 Engineering
2 2.0 Bob 20 Marketing
3 5.0 Eve 20 Marketing
4 NaN NaN 40 SalesO departamento de Vendas (dept_id=40) agora aparece mesmo que nenhum funcionário pertença a ele. Os campos de funcionário são NaN para essa linha.
Quando usar right merge: Na prática, right merges são raros. Você sempre pode reescrever um right merge como um left merge trocando a ordem dos DataFrames. A maioria das bases de código prefere left merges por consistência.
Outer Merge (Full Outer Join)
Um outer merge retorna todas as linhas de ambos os DataFrames. Onde não há correspondência, os valores ausentes são preenchidos com NaN.
outer_result = pd.merge(employees, departments, on='dept_id', how='outer')
print(outer_result)Saída:
emp_id name dept_id dept_name
0 1.0 Alice 10 Engineering
1 3.0 Charlie 10 Engineering
2 2.0 Bob 20 Marketing
3 5.0 Eve 20 Marketing
4 4.0 Diana 30 NaN
5 NaN NaN 40 SalesTanto Diana (sem departamento correspondente) quanto Vendas (sem funcionários correspondentes) aparecem no resultado.
Quando usar outer merge: Use quando você precisar de uma imagem completa de ambos os conjuntos de dados e quiser identificar quais linhas falharam ao corresponder. O parâmetro indicator é especialmente útil aqui.
Comparação rápida dos tipos de merge
| Tipo de merge | Mantém da esquerda | Mantém da direita | Linhas não correspondidas |
|---|---|---|---|
inner | Apenas correspondidas | Apenas correspondidas | Descartadas |
left | Todas as linhas | Apenas correspondidas | Linhas esquerdas mantidas, direita preenche NaN |
right | Apenas correspondidas | Todas as linhas | Linhas direitas mantidas, esquerda preenche NaN |
outer | Todas as linhas | Todas as linhas | Ambos os lados mantidos, NaN onde não há correspondência |
cross | Todas as linhas | Todas as linhas | Produto cartesiano (todas as combinações) |
Mesclando em várias colunas
Quando uma única coluna não é suficiente para identificar exclusivamente uma correspondência, passe uma lista de nomes de colunas para on:
sales = pd.DataFrame({
'year': [2024, 2024, 2025, 2025],
'quarter': ['Q1', 'Q2', 'Q1', 'Q2'],
'revenue': [100, 150, 200, 250]
})
targets = pd.DataFrame({
'year': [2024, 2024, 2025, 2025],
'quarter': ['Q1', 'Q2', 'Q1', 'Q2'],
'target': [120, 140, 210, 230]
})
merged = pd.merge(sales, targets, on=['year', 'quarter'])
print(merged)Saída:
year quarter revenue target
0 2024 Q1 100 120
1 2024 Q2 150 140
2 2025 Q1 200 210
3 2025 Q2 250 230Isso é o equivalente a uma chave composta em SQL. Tanto year quanto quarter devem corresponder para que as linhas sejam unidas.
Mesclando com nomes de colunas diferentes
Às vezes, os dois DataFrames usam nomes diferentes para o mesmo conceito. Use left_on e right_on em vez de on:
orders = pd.DataFrame({
'order_id': [101, 102, 103],
'customer_id': [1, 2, 3],
'amount': [50.0, 75.0, 120.0]
})
customers = pd.DataFrame({
'id': [1, 2, 4],
'name': ['Alice', 'Bob', 'Diana']
})
merged = pd.merge(orders, customers, left_on='customer_id', right_on='id', how='left')
print(merged)Saída:
order_id customer_id amount id name
0 101 1 50.0 1.0 Alice
1 102 2 75.0 2.0 Bob
2 103 3 120.0 NaN NaNObserve que tanto as colunas customer_id quanto id aparecem no resultado. Você pode descartar a duplicata depois:
merged = merged.drop(columns=['id'])Tratamento de nomes de colunas duplicados com sufixos
Quando ambos os DataFrames têm colunas com o mesmo nome (além da chave), o pandas adiciona sufixos para distingui-las:
df1 = pd.DataFrame({
'id': [1, 2, 3],
'score': [85, 90, 78]
})
df2 = pd.DataFrame({
'id': [1, 2, 3],
'score': [88, 92, 80]
})
# Sufixos padrão
merged = pd.merge(df1, df2, on='id')
print(merged)Saída:
id score_x score_y
0 1 85 88
1 2 90 92
2 3 78 80Você pode personalizar os sufixos para tornar os nomes das colunas mais significativos:
merged = pd.merge(df1, df2, on='id', suffixes=('_midterm', '_final'))
print(merged)Saída:
id score_midterm score_final
0 1 85 88
1 2 90 92
2 3 78 80Usando o parâmetro indicator
O parâmetro indicator adiciona uma coluna _merge que informa de onde cada linha veio:
result = pd.merge(employees, departments, on='dept_id', how='outer', indicator=True)
print(result)Saída:
emp_id name dept_id dept_name _merge
0 1.0 Alice 10 Engineering both
1 3.0 Charlie 10 Engineering both
2 2.0 Bob 20 Marketing both
3 5.0 Eve 20 Marketing both
4 4.0 Diana 30 NaN left_only
5 NaN NaN 40 Sales right_onlyIsso é extremamente útil para verificações de qualidade de dados -- você pode filtrar rapidamente as linhas que falharam ao corresponder:
unmatched = result[result['_merge'] != 'both']
print(unmatched)merge() vs join() vs concat() -- Quando usar cada um
O Pandas oferece três maneiras de combinar DataFrames. Aqui está quando usar cada uma:
| Recurso | pd.merge() | df.join() | pd.concat() |
|---|---|---|---|
| Tipo de junção | Baseado em colunas (como SQL) | Baseado em índice por padrão | Empilhar linhas ou colunas |
| Sintaxe | pd.merge(df1, df2, on='col') | df1.join(df2, on='col') | pd.concat([df1, df2]) |
| Melhor para | Junção em colunas compartilhadas | Junção em índice | Empilhar DataFrames vertical/horizontalmente |
| Várias chaves | Sim (on=['a','b']) | Limitado | Não aplicável |
| Vários DataFrames | Dois de cada vez | Dois de cada vez | Qualquer número de uma vez |
| Junção padrão | Inner | Left | Outer (axis=0) |
| Flexibilidade | Mais alta | Média | Caso de uso diferente |
Regra geral:
- Use
pd.merge()quando você estiver combinando DataFrames com base em valores de colunas (o caso mais comum). - Use
df.join()quando sua chave de junção for o índice e você quiser uma sintaxe mais curta. - Use
pd.concat()quando você estiver empilhando DataFrames uns sobre os outros (anexando linhas) ou lado a lado.
Erros comuns e solução de problemas
1. MergeError: colunas se sobrepõem mas nenhum sufixo especificado
Isso acontece quando ambos os DataFrames têm colunas não-chave com o mesmo nome e você define suffixes=(False, False):
# Correção: use sufixos significativos
merged = pd.merge(df1, df2, on='id', suffixes=('_left', '_right'))2. Explosão inesperada de linhas (merge muitos-para-muitos)
Se ambos os DataFrames tiverem valores duplicados na chave de junção, o pandas cria um produto cartesiano das linhas correspondentes. Isso pode fazer com que seu resultado tenha muito mais linhas do que qualquer entrada:
# Verificar duplicatas antes de mesclar
print(df1['key'].duplicated().sum())
print(df2['key'].duplicated().sum())
# Use validate para detectar isso cedo
merged = pd.merge(df1, df2, on='key', validate='one_to_many')O parâmetro validate aceita 'one_to_one', 'one_to_many', 'many_to_one' e 'many_to_many'. Ele lança um MergeError se os dados não corresponderem à cardinalidade esperada.
3. Coluna chave tem dtypes diferentes
Se um DataFrame armazena a chave como int64 e o outro como object (string), o merge falhará ou produzirá zero correspondências:
# Verificar dtypes
print(df1['id'].dtype) # int64
print(df2['id'].dtype) # object
# Correção: converter para o mesmo tipo
df2['id'] = df2['id'].astype(int)
merged = pd.merge(df1, df2, on='id')4. Valores NaN nas chaves
Linhas com NaN na coluna de chave de junção não corresponderão a nada (NaN != NaN no pandas). Descarte ou preencha-as primeiro:
df1 = df1.dropna(subset=['key'])Visualize seus DataFrames mesclados com PyGWalker
Depois de mesclar seus dados, o próximo passo geralmente é explorar o resultado -- observar distribuições, identificar padrões e verificar anomalias. Em vez de escrever dezenas de chamadas matplotlib ou seaborn, você pode usar PyGWalker (opens in a new tab), uma biblioteca Python de código aberto que transforma qualquer DataFrame pandas em uma interface de exploração visual interativa semelhante ao Tableau diretamente dentro do Jupyter Notebook.
import pandas as pd
import pygwalker as pyg
# Mescle seus DataFrames
employees = pd.DataFrame({
'emp_id': [1, 2, 3, 4, 5],
'name': ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'],
'dept_id': [10, 20, 10, 30, 20],
'salary': [95000, 82000, 105000, 78000, 91000]
})
departments = pd.DataFrame({
'dept_id': [10, 20, 30],
'dept_name': ['Engineering', 'Marketing', 'Design']
})
merged = pd.merge(employees, departments, on='dept_id')
# Inicie visualização interativa -- arraste e solte para explorar
walker = pyg.walk(merged)Com o PyGWalker, você pode arrastar dept_name para o eixo x e salary para o eixo y para ver instantaneamente a distribuição de salários por departamento -- nenhum código de gráfico necessário. Você pode criar gráficos de barras, gráficos de dispersão, histogramas e muito mais apenas arrastando campos. É especialmente poderoso para explorar os resultados de merges complexos onde você precisa verificar se a junção funcionou como esperado.
Você pode experimentar o PyGWalker agora no Google Colab (opens in a new tab), Kaggle (opens in a new tab), ou instalá-lo com
pip install pygwalker.
FAQ
Qual é a diferença entre pandas merge e join?
pd.merge() une DataFrames com base em valores de colunas por padrão e suporta todos os tipos de junção (inner, left, right, outer, cross). df.join() une no índice por padrão e usa uma junção left. Por baixo dos panos, join() chama merge(), então eles produzem os mesmos resultados -- merge() simplesmente lhe dá mais controle sobre quais colunas corresponder.
Como mesclo dois DataFrames em várias colunas no pandas?
Passe uma lista de nomes de colunas para o parâmetro on: pd.merge(df1, df2, on=['col_a', 'col_b']). Ambas as colunas devem corresponder para que as linhas sejam unidas. Isso é equivalente a uma chave composta em SQL.
Por que meu pandas merge cria linhas duplicadas?
Linhas duplicadas aparecem quando a chave de junção tem valores repetidos em um ou ambos os DataFrames. O Pandas cria um produto cartesiano de todas as linhas correspondentes. Use df.duplicated(subset=['key']).sum() para verificar duplicatas antes de mesclar, ou use validate='one_to_one' para detectá-las cedo.
O que é um cross merge no pandas?
Um cross merge (how='cross') produz o produto cartesiano de ambos os DataFrames -- cada linha da esquerda é emparelhada com cada linha da direita. Se a esquerda tem 3 linhas e a direita tem 4 linhas, o resultado tem 12 linhas. É útil para gerar todas as combinações possíveis, como emparelhar cada produto com cada localização de loja.
Como faço um pandas merge no índice?
Defina left_index=True e/ou right_index=True: pd.merge(df1, df2, left_index=True, right_index=True). Você também pode misturar chaves de índice e coluna: pd.merge(df1, df2, left_on='col_a', right_index=True).
Conclusão
A função merge() do pandas é a ferramenta mais flexível e amplamente usada para combinar DataFrames em Python. Para recapitular os pontos principais:
- Inner merge (padrão) mantém apenas linhas que correspondem em ambos os DataFrames.
- Left merge mantém todas as linhas do DataFrame esquerdo, preenchendo NaN onde a direita não tem correspondência.
- Right merge mantém todas as linhas do DataFrame direito -- mas prefira left merge com ordem trocada por consistência.
- Outer merge mantém tudo de ambos os lados, útil para identificar registros não correspondidos com
indicator=True. - Use
onpara chaves de mesmo nome,left_on/right_onpara chaves de nomes diferentes esuffixespara lidar com colunas sobrepostas. - Sempre verifique chaves duplicadas e dtypes incompatíveis antes de mesclar para evitar resultados inesperados.
Uma vez que seus dados estão mesclados, ferramentas como PyGWalker (opens in a new tab) permitem que você explore visualmente o resultado sem escrever código de gráfico, tornando todo o fluxo de trabalho de análise mais rápido e intuitivo.