Junções à esquerda e à direita
Execute junções à esquerda e à direita para preservar todas as linhas de uma tabela ao mesmo tempo que combina registros de outra.
Junções à esquerda e à direita é uma aula grátis de Pandas & NumPy Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Pandas & NumPy Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Pandas & NumPy Academy inclui 4 aulas no total.
Joins assimétricos
Joins internos e externos tratam ambos os DataFrames de forma simétrica. Porém, muitas vezes você deseja preservar todos os registros de uma tabela e enriquecê-los com dados de outra. É nesse caso que entram os joins à esquerda e os joins à direita. Esses joins assimétricos são extremamente comuns em análises: manter todas as transações e acrescentar os nomes dos produtos quando disponíveis; manter todos os usuários e acrescentar a data da última compra quando houver uma.
Join à esquerda: preservando todas as linhas esquerdas
Um join à esquerda (how='left') mantém todas as linhas do DataFrame esquerdo. Para as linhas que encontram uma chave correspondente no DataFrame direito, as colunas direitas são preenchidas com os valores correspondentes. Para as linhas sem correspondência, as colunas direitas são preenchidas com NaN. A quantidade de linhas do resultado sempre é igual à quantidade de linhas do DataFrame esquerdo (desde que não haja chaves duplicadas).
import pandas as pd
orders = pd.DataFrame({
'order_id': [1, 2, 3, 4],
'customer_id': [101, 102, 101, 999],
'amount': [250, 80, 320, 150]
})
customers = pd.DataFrame({
'customer_id': [101, 102, 103],
'name': ['Alice', 'Bob', 'Carol']
})
result = pd.merge(orders, customers, on='customer_id', how='left')
print(result)
# All 4 orders kept; order with customer_id=999 gets NaN for nameEstrutura do resultado de um join à esquerda
Após um join à esquerda, as linhas do DataFrame esquerdo que não encontraram correspondência no lado direito terão NaN em todas as colunas provenientes da tabela direita. Você pode usar isso para identificar linhas sem correspondência com um filtro booleano em uma coluna da tabela direita e contar quantas linhas esquerdas não encontraram correspondência — uma verificação útil da qualidade dos dados.
result = pd.merge(orders, customers, on='customer_id', how='left')
print(result)
# order_id customer_id amount name
# 0 1 101 250 Alice
# 1 2 102 80 Bob
# 2 3 101 320 Alice
# 3 4 999 150 NaN <- no matching customer
# Count unmatched
unmatched = result['name'].isna().sum()
print(f'{unmatched} orders have no customer record')Quando usar um join à esquerda
Joins à esquerda são apropriados quando o DataFrame esquerdo é a tabela principal e a tabela direita é complementar. Cenários comuns incluem: enriquecer uma tabela de fatos com uma tabela de dimensões (pedidos + nomes de produtos), adicionar metadados opcionais (usuários + dados de perfil) ou calcular métricas para todos os registros mesmo quando uma consulta falha. Na maioria dos códigos de análise, joins à esquerda são muito mais comuns do que joins à direita.
# Realistic pattern: enrich all products with optional category data
products = pd.DataFrame({'sku': ['A1', 'B2', 'C3'], 'price': [10, 20, 15]})
categories = pd.DataFrame({'sku': ['A1', 'C3'], 'category': ['Tools', 'Home']})
# Keep all products; add category where available
enriched = pd.merge(products, categories, on='sku', how='left')
print(enriched)
# sku price category
# 0 A1 10 Tools
# 1 B2 20 NaN
# 2 C3 15 HomeJoin à direita: preservando todas as linhas direitas
Um join à direita (how='right') é o equivalente espelhado de um join à esquerda: ele mantém todas as linhas do DataFrame direito e preenche com NaN as colunas da tabela esquerda quando não há correspondência. Um join à direita é menos comum porque você sempre pode obter o mesmo resultado trocando os argumentos dos DataFrames e usando um join à esquerda, que é mais claro para quem lê o código.
# Right join: keep all customers, attach orders where they exist
result = pd.merge(orders, customers, on='customer_id', how='right')
print(result)
# All 3 customers appear; Carol (103) has NaN for order_id and amount
# Equivalent left join (swap arguments):
result2 = pd.merge(customers, orders, on='customer_id', how='left')
# Same data, just column order differsComparando os quatro tipos de join
Os quatro tipos de join diferem apenas em quais linhas do lado sem correspondência são preservadas. inner: somente linhas correspondentes. outer: todas as linhas dos dois lados. left: todas as linhas esquerdas. right: todas as linhas direitas. Para entradas sem correspondência, as colunas do lado ausente são preenchidas com NaN. Escolher corretamente é essencial para evitar descartar ou duplicar registros silenciosamente.
# Summary table
# how='inner' : rows in BOTH tables
# how='left' : ALL left rows + matched right
# how='right' : matched left + ALL right rows
# how='outer' : ALL left rows + ALL right rows
# Test each
for how in ['inner', 'left', 'right', 'outer']:
r = pd.merge(orders, customers, on='customer_id', how=how)
print(f'{how}: {len(r)} rows')Preenchendo NaN nos resultados de joins à esquerda
Após um join à esquerda, as linhas sem correspondência têm NaN nas colunas da tabela direita. Muitas vezes, você desejará preencher esses valores com padrões adequados — por exemplo, 'Unknown' para uma categoria ausente ou 0 para uma contagem ausente. Use fillna() no resultado ou passe fill_value nas operações aritméticas realizadas após o join.
result = pd.merge(products, categories, on='sku', how='left')
result['category'] = result['category'].fillna('Uncategorised')
print(result)
# sku price category
# 0 A1 10 Tools
# 1 B2 20 Uncategorised
# 2 C3 15 HomeAnti-join à esquerda: linhas sem correspondência
Um padrão útil que não é diretamente oferecido por how é o anti-join: manter apenas as linhas esquerdas que NÃO têm correspondência na tabela direita. Implemente-o com um join à esquerda usando indicator=True e, em seguida, filtre por _merge == 'left_only'. Isso é perfeito para encontrar registros órfãos, itens novos que não estão em uma lista de referência ou transações ausentes em um livro-caixa.
# Anti-join: orders with no matching customer record
result = pd.merge(orders, customers, on='customer_id',
how='left', indicator=True)
unmatched_orders = result[result['_merge'] == 'left_only'].drop(columns='_merge')
print(unmatched_orders)
# order_id customer_id amount name
# 3 4 999 150 NaNPreservando a quantidade de linhas com um join à esquerda
Quando o DataFrame direito tem chaves exclusivas, um join à esquerda garante a preservação exata da quantidade de linhas da tabela esquerda. Porém, se a tabela direita tiver valores de chave duplicados, o join à esquerda multiplicará as linhas, assim como um join interno. Sempre confirme que a quantidade de linhas do resultado corresponde à da tabela esquerda quando você espera um relacionamento de um para muitos.
# Right table has duplicate keys -> row multiplication
orders_small = pd.DataFrame({'id': [1, 2], 'amount': [100, 200]})
multi_customer = pd.DataFrame({
'id': [1, 1], # duplicate!
'contact': ['Alice', 'Alice2']
})
result = pd.merge(orders_small, multi_customer, on='id', how='left')
print(len(result)) # 3 rows! order 1 appears twice
print(result)Padrão de join à esquerda no mundo real
Veja um fluxo de trabalho completo do mundo real: comece com um registro de transações, faça um join à esquerda com um catálogo de produtos para obter os nomes e, em seguida, faça outro join à esquerda com uma tabela de clientes para obter os nomes. Preencha as consultas sem resultado com valores padrão. A sequência de joins à esquerda garante que cada linha de transação seja preservada, mesmo que o registro do produto ou do cliente esteja ausente nas tabelas de referência.
transactions = pd.DataFrame({
'txn_id': [1, 2, 3],
'cust_id': [10, 11, 99],
'prod_id': [20, 21, 20],
'total': [50, 30, 70]
})
custs = pd.DataFrame({'cust_id': [10, 11], 'cust_name': ['Alice', 'Bob']})
prods = pd.DataFrame({'prod_id': [20, 21], 'prod_name': ['Widget', 'Gadget']})
result = (
transactions
.merge(custs, on='cust_id', how='left')
.merge(prods, on='prod_id', how='left')
)
print(result)Decisão entre join à esquerda e join interno
A escolha entre um join à esquerda e um join interno é uma decisão de lógica de negócio: você deve manter registros que não têm correspondência na consulta ou descartá-los silenciosamente? Use o join à esquerda quando consultas sem resultado forem aceitáveis e você quiser manter todos os registros principais. Use o join interno quando uma consulta sem resultado significar que o registro é inválido e deve ser excluído da análise. Sempre documente qual opção escolheu e por quê.
# Left join: keep all transactions (some may have no product name)
result_left = pd.merge(transactions, prods, on='prod_id', how='left')
print('Left join rows:', len(result_left)) # same as transactions
# Inner join: only transactions with known product
result_inner = pd.merge(transactions, prods, on='prod_id', how='inner')
print('Inner join rows:', len(result_inner)) # may be fewerVerificação rápida
Teste sua compreensão dos joins à esquerda e à direita abordados nesta lição.
Recapitulação da lição
Nesta lição, você aprendeu: o join à esquerda preserva todas as linhas do DataFrame esquerdo, preenchendo as colunas direitas com NaN quando não há correspondência; o join à direita é o equivalente espelhado; o padrão de anti-join usando indicator=True encontra linhas esquerdas sem correspondência à direita; e a escolha entre um join à esquerda e um join interno é uma decisão de lógica de negócio. Em seguida, exploraremos como fazer joins de DataFrames usando o índice em vez de uma coluna.
Aprenda Python com um tutor de IA — grátis
Escreva e execute código real no seu navegador, obtenha ajuda instantânea de um tutor de IA 24/7 e continue de onde parou na web ou no app.
- Cursos
- 30
- Aulas
- 120
Perguntas Frequentes
A aula “Junções à esquerda e à direita” é grátis?
Sim — o texto completo de “Junções à esquerda e à direita” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Pandas & NumPy Academy, atualize para CoddyKit PRO. O curso de Pandas & NumPy Academy inclui 4 aulas no total.
O que vou aprender em “Junções à esquerda e à direita”?
Execute junções à esquerda e à direita para preservar todas as linhas de uma tabela ao mesmo tempo que combina registros de outra. Você pratica Pandas & NumPy Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Pandas & NumPy Academy?
Nenhuma experiência prévia é necessária. Pandas & NumPy Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.
Quanto tempo leva a aula “Junções à esquerda e à direita”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Pandas & NumPy Academy?
Sim. Cada aula de Pandas & NumPy Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- pd.concat para empilhar DataFrames
- pd.merge: junções internas e externas
- Junções à esquerda e à direita
- Fazendo junções pelo índice