Aula 10.3 - Análise e visualização de dados em Python - biblioteca pandas (parte 8)
Apenas mais uma função no pandas, e podemos dar essa jornada de juntar dados como encerrada. Ao menos por enquanto…

Nas últimas aulas desta série, vimos o poder do pandas para fazer junções de diferentes fontes de dados, facilitando assim a vida de quem tem precisado lidar com tabelas fragmentadas. Até o momento, discutimos com mais detalhes as funções concat() e merge(); falta-nos agora a apresentação da última função, join().
O nome já diz: a função join()
Quando você vê o nome da função, join(), é possível que pense outra vez na cláusula JOIN do SQL. E a verdade é… que é por aí mesmo. Veja a tabela abaixo; a função do pandas nada mais é que uma “tradução” das funções de JOIN para uma forma a ser utilizada através de uma biblioteca Python.
| pandas join() | SQL JOIN | Operação |
| how='inner' | INNER JOIN | Retorna apenas registros que correspondem em ambas as fontes |
| how='left' | LEFT JOIN | Retorna todos os registros da fonte esquerda + correspondências da direita |
| how='right' | RIGHT JOIN | Retorna todos os registros da fonte direita + correspondências da esquerda |
| how='outer' | FULL OUTER JOIN | Retorna todos os registros de ambas as fontes |
Agora, se você está conosco há algum tempo e se lembra das aulas anteriores, essas informações vão parecer um tanto familiares. E são familiares mesmo! Perceba que as características batem com uma outra função do pandas, merge().
Mas é tudo igual mesmo? Comparando join() com merge()
É possível que você pense que a função join()seja uma mera redundância do merge(), e que a escolha de qual recurso utilizar é indiferente quando se quer fazer uma combinação de DataFrames. No entanto, as coisas não precisam ser (e não são, na verdade) assim. Dê uma olhada na tabela abaixo; aqui você verá duas coisas: apontamentos sobre as diferenças entre as funções do pandas e a equivalência com a cláusula do SQL.
| Característica | pandas join() | pandas merge() | SQL JOIN |
| Uso Principal | Combinar DataFrames baseado em índices | Combinar DataFrames baseado em colunas | Combinar tabelas baseado em colunas |
| Sintaxe Básica | df1.join(df2) | df1.merge(df2, on='coluna') | SELECT * FROM t1 JOIN t2 ON t1.col = t2.col |
| Base da Junção | Índices por padrão, pode usar colunas com on | Colunas específicas usando on, left_on, right_on | Colunas específicas usando cláusula ON |
| Tipos de Join | - how='left'- how='right'- how='inner'- how='outer' | - how='left'- how='right'- how='inner'- how='outer'- how='cross' | - LEFT JOIN- RIGHT JOIN- INNER JOIN- FULL OUTER JOIN- CROSS JOIN |
| Tratamento de Colunas Duplicadas | Usa lsuffix e rsuffix | Usa suffixes | Requer aliases explícitos na consulta |
| Melhor Para | - Junções simples baseadas em índice - Dados já indexados corretamente - Operações mais diretas | - Junções complexas - Múltiplas colunas de junção - Maior flexibilidade | - Junções complexas - Múltiplas condições - Operações em banco de dados |
| Limitações | - Menos flexível para junções complexas - Primariamente focado em índices | - Sintaxe mais verbosa - Pode ser complexo para junções simples | - Requer conhecimento de SQL - Menos integrado com análise de dados em Python |
| Performance | Melhor para junções baseadas em índice | Melhor para junções complexas de DataFrames | Otimizado para operações em banco de dados |
Desta tabela, uma coisa fica clara: enquanto merge() dá a possibilidade de combinar DataFrames baseados em colunas, a concentração de join() se dá nos índices do DataFrame. Para lembrar o que são índices para o pandas:
The index of a DataFrame is a series of labels that identify each row. The labels can be integers, strings, or any other hashable type. The index is used for label-based access and alignment, and can be accessed or modified using this attribute.
Traduzindo, é algo assim:
O índice de um DataFrame é uma série de etiquetas (labels) que identificam cada linha. Podem ser números inteiros, strings, ou qualquer tipo de dado que possa ser utilizada como chave. É utilizado para acesso e alinhamento de dados baseando-se em etiquetas, podendo acessar e modificar linhas usando esse mesmo atributo.
Então, em vez de nos orientarmos pelos nomes das colunas, como em merge(), podemos nos valer de, digamos, os “nomes” das linhas usando o join().
Um exemplo prático
Comecemos o exemplo criando dois DataFrames de características envolvendo aspectos corpóreos de um grupo limitado de aves. Nesse caso, como usaremos o join(), daremos uma atenção especial aos índices de cada DataFrame. Cada linha das tabelas possuirá um nome científico de uma ave em específico.
import pandas as pd
import numpy as np
# Criando DataFrame com dados das asas
df_asas = pd.DataFrame({
'envergadura_cm': [240, 180, 85, 120, 300],
'comp_dedo_medio_cm': [12, 8, 4, 6, 15],
'comp_asa_cm': [110, 85, 40, 55, 145]
}, index=['Aquila chrysaetos', # Águia-real
'Buteo buteo', # Águia-de-asa-redonda
'Falco tinnunculus', # Peneireiro-vulgar
'Accipiter nisus', # Gavião-da-europa
'Gyps fulvus']) # Grifo
# Criando DataFrame com dados das pernas
df_pernas = pd.DataFrame({
'comp_tarso_cm': [9.5, 7.2, 4.5, 5.8, 10.2],
'comp_total_perna_cm': [35, 28, 18, 22, 40],
'circunf_tarso_cm': [8, 6, 3, 4, 9]
}, index=['Aquila chrysaetos', # Águia-real
'Buteo buteo', # Águia-de-asa-redonda
'Falco tinnunculus', # Peneireiro-vulgar
'Strix aluco', # Coruja-do-mato
'Gyps fulvus']) # Grifo
Perceba já de início que existem alguns índices que possuem nomes iguais (que é o intuito dessa atividade); esta parte é muito importante para usar o join(). A partir daqui, então, já podemos “traduzir” as cláusulas do SQL para argumentos da função, assim como fizemos com o merge() anteriormente, como no bloco de código abaixo:
# Exemplo 1: Inner join (apenas espécies que aparecem em ambos os DataFrames)
df_inner = df_asas.join(df_pernas, how='inner')
# Exemplo 2: Left join (todas as espécies do DataFrame de asas)
df_left = df_asas.join(df_pernas, how='left')
# Exemplo 3: Right join (todas as espécies do DataFrame de pernas)
df_right = df_asas.join(df_pernas, how='right')
# Exemplo 4: Outer join (todas as espécies de ambos os DataFrames)
df_outer = df_asas.join(df_pernas, how='outer')
Como resultado, teremos para cada variável criada um DataFrame com os dados de asas e pernas de aves conforme o tipo de JOIN selecionado. Note que existem espécies que ocorrem em apenas uma das tabelas. Isso não vem a atrapalhar a mescla como um todo, mas é importante salientar que, no caso das colunas referentes ao outro DataFrame (onde a espécie não está descrita), os dados virão nulos.
O resumo da ópera
Chegando ao final das discussões sobre as diferentes formas de mesclar DataFrames usando pandas, podemos resumir tudo em uma tabela como esta abaixo, estabelecendo também comparações com a cláusula JOIN do SQL:
Comparação entre métodos de junção pandas e SQL
Comparação entre métodos de junção pandas e SQL
| Característica | pandas join() | pandas merge() | pandas concat() | SQL JOIN |
| Uso Principal | Combinar DataFrames baseado em índices | Combinar DataFrames baseado em colunas | Empilhar DataFrames (vertical ou horizontal) | Combinar tabelas baseado em colunas |
| Sintaxe Básica | df1.join(df2) | df1.merge(df2, on='coluna') | pd.concat([df1, df2]) | SELECT * FROM t1 JOIN t2 ON t1.col = t2.col |
| Base da Junção | Índices por padrão, pode usar colunas com on | Colunas específicas usando on, left_on, right_on | Posição (eixo) dos DataFrames | Colunas específicas usando cláusula ON |
| Tipos de Operação | - how='left'- how='right'- how='inner'- how='outer' | - how='left'- how='right'- how='inner'- how='outer'- how='cross' | - axis=0 (vertical)- axis=1 (horizontal)- join='outer'- join='inner' | - LEFT JOIN- RIGHT JOIN- INNER JOIN- FULL OUTER JOIN- CROSS JOIN |
| Tratamento de Duplicatas | Usa lsuffix e rsuffix | Usa suffixes | Usa ignore_index e keys | Requer aliases explícitos na consulta |
| Melhor Para | - Junções simples baseadas em índice - Dados já indexados corretamente - Operações mais diretas | - Junções complexas - Múltiplas colunas de junção - Maior flexibilidade | - Combinar DataFrames sequencialmente - Empilhar dados vertical/horizontalmente - Manter índices originais | - Junções complexas - Múltiplas condições - Operações em banco de dados |
| Limitações | - Menos flexível para junções complexas - Primariamente focado em índices | - Sintaxe mais verbosa - Pode ser complexo para junções simples | - Não faz junção baseada em valores - Limitado a operações de empilhamento | - Requer conhecimento de SQL - Menos integrado com análise em Python |
| Performance | Melhor para junções baseadas em índice | Melhor para junções complexas de DataFrames | Eficiente para empilhamento simples | Otimizado para operações em banco de dados |
| Exemplo de Uso Comum | Combinar dados financeiros usando datas como índice | Combinar dados de vendas usando ID do cliente | Combinar relatórios mensais sequencialmente | Combinar dados de diferentes tabelas relacionais |
Esta é, portanto, a última aula que explora as três funções que podemos usar para juntar tabelas usando o pandas: concat(), join(), e merge(). Continuaremos a explorar outros atributos do pandas e do Python para analisar dados, especialmente os dados ecológicos, nas próximas aulas a serem publicadas em breve.
Aproveite o conteúdo para seguir estudando! Um abraço e até a próxima!
Para ler mais:





