Pandas Concat: Como concatenar DataFrames em Python
Updated on
Dados do mundo real raramente estão em um único arquivo. Você extrai as vendas de janeiro de um CSV, as de fevereiro de outro e as metas do Q1 de um terceiro. Você faz scraping de várias páginas web em DataFrames separados. Você divide um grande conjunto de dados para processamento paralelo e precisa remontar as peças. Em todos os casos, você precisa de uma forma confiável de combinar DataFrames sem perder linhas, embaralhar colunas ou corromper seu índice.
A função pandas concat (pd.concat()) é a ferramenta padrão para essa tarefa. Ela empilha DataFrames verticalmente (adicionando linhas) ou horizontalmente (adicionando colunas), lida com colunas diferentes de forma elegante e escala para qualquer número de DataFrames em uma única chamada. Este guia cobre todos os parâmetros que você precisa, com exemplos de código funcionais que você pode colar diretamente no seu notebook.
O que pd.concat() faz -- Sintaxe básica
pd.concat() recebe uma lista (ou dicionário) de DataFrames e os une ao longo de um eixo especificado. Pense nisso como empilhar blocos de construção -- verticalmente para adicionar mais linhas, ou lado a lado para adicionar mais colunas.
import pandas as pd
result = pd.concat(
objs, # list or dict of DataFrames
axis=0, # 0 = vertical (rows), 1 = horizontal (columns)
join='outer', # 'outer' or 'inner'
ignore_index=False,
keys=None,
sort=False,
verify_integrity=False
)Parâmetros principais em resumo
| Parâmetro | Descrição | Padrão |
|---|---|---|
objs | Uma lista ou dicionário de DataFrames (ou Series) para concatenar | Obrigatório |
axis | 0 para empilhar linhas (vertical), 1 para empilhar colunas (horizontal) | 0 |
join | 'outer' mantém todas as colunas; 'inner' mantém apenas colunas compartilhadas | 'outer' |
ignore_index | Se True, redefine o índice para 0, 1, 2, ... no resultado | False |
keys | Rótulos para identificar de qual DataFrame original cada linha veio | None |
sort | Ordenar eixo de não concatenação (nomes de colunas para axis=0) | False |
verify_integrity | Levantar erro se o resultado tiver valores de índice duplicados | False |
Dados de exemplo para todos os exemplos
Todos os exemplos abaixo usam estes DataFrames:
import pandas as pd
df_jan = pd.DataFrame({
'product': ['Widget', 'Gadget', 'Sprocket'],
'units_sold': [150, 200, 80],
'revenue': [1500, 3000, 960]
})
df_feb = pd.DataFrame({
'product': ['Widget', 'Gadget', 'Sprocket'],
'units_sold': [170, 180, 95],
'revenue': [1700, 2700, 1140]
})
print(df_jan)
print(df_feb)Saída:
product units_sold revenue
0 Widget 150 1500
1 Gadget 200 3000
2 Sprocket 80 960
product units_sold revenue
0 Widget 170 1700
1 Gadget 180 2700
2 Sprocket 95 1140Concatenando DataFrames verticalmente (axis=0)
A concatenação vertical é o caso de uso mais comum. Ela empilha um DataFrame sobre o outro, adicionando linhas. É o que você usa quando tem arquivos mensais, resultados em lote ou quaisquer dados divididos em várias tabelas com as mesmas colunas.
combined = pd.concat([df_jan, df_feb])
print(combined)Saída:
product units_sold revenue
0 Widget 150 1500
1 Gadget 200 3000
2 Sprocket 80 960
0 Widget 170 1700
1 Gadget 180 2700
2 Sprocket 95 1140Observe o índice: ambos os DataFrames mantiveram seus valores de índice originais (0, 1, 2), então o resultado tem valores de índice duplicados. Isso geralmente não é o que você quer. A solução é o parâmetro ignore_index, abordado a seguir.
O parâmetro ignore_index -- Redefinindo o índice
Definir ignore_index=True descarta o índice original e atribui um novo índice sequencial começando de 0:
combined = pd.concat([df_jan, df_feb], ignore_index=True)
print(combined)Saída:
product units_sold revenue
0 Widget 150 1500
1 Gadget 200 3000
2 Sprocket 80 960
3 Widget 170 1700
4 Gadget 180 2700
5 Sprocket 95 1140Quando usar: Quase sempre ao concatenar verticalmente. A menos que seu índice contenha informações significativas (como timestamps ou IDs únicos), redefina-o para evitar confusão posterior.
O parâmetro keys -- Criando um índice hierárquico
O parâmetro keys adiciona um nível ao índice que rotula de qual fonte cada linha veio. Isso cria um MultiIndex (índice hierárquico):
combined = pd.concat([df_jan, df_feb], keys=['January', 'February'])
print(combined)Saída:
product units_sold revenue
January 0 Widget 150 1500
1 Gadget 200 3000
2 Sprocket 80 960
February 0 Widget 170 1700
1 Gadget 180 2700
2 Sprocket 95 1140Você pode então selecionar dados de uma fonte específica usando .loc:
# Get only January data
jan_data = combined.loc['January']
print(jan_data)Saída:
product units_sold revenue
0 Widget 150 1500
1 Gadget 200 3000
2 Sprocket 80 960Quando usar: Use keys quando precisar rastrear a qual DataFrame original cada linha pertence -- por exemplo, dados de diferentes experimentos, períodos de tempo ou fontes de dados.
Concatenando horizontalmente (axis=1) -- Lado a lado
Definir axis=1 coloca DataFrames lado a lado, adicionando colunas. O Pandas alinha as linhas pelos seus valores de índice.
targets = pd.DataFrame({
'target_units': [160, 190, 90],
'target_revenue': [1600, 2850, 1080]
})
result = pd.concat([df_jan, targets], axis=1)
print(result)Saída:
product units_sold revenue target_units target_revenue
0 Widget 150 1500 160 1600
1 Gadget 200 3000 190 2850
2 Sprocket 80 960 90 1080Isso funciona corretamente porque ambos os DataFrames compartilham o mesmo índice (0, 1, 2). Se os índices não estiverem alinhados, você obtém valores NaN para as linhas que não correspondem:
df_a = pd.DataFrame({'value_a': [10, 20, 30]}, index=[0, 1, 2])
df_b = pd.DataFrame({'value_b': [40, 50, 60]}, index=[1, 2, 3])
result = pd.concat([df_a, df_b], axis=1)
print(result)Saída:
value_a value_b
0 10.0 NaN
1 20.0 40.0
2 30.0 50.0
3 NaN 60.0A linha 0 não tem value_b (sem índice correspondente em df_b), e a linha 3 não tem value_a (sem índice correspondente em df_a).
O parâmetro join -- Inner vs Outer
O parâmetro join controla o que acontece quando DataFrames têm colunas diferentes (para axis=0) ou valores de índice diferentes (para axis=1).
outer join (padrão) -- Manter tudo
df_with_extra = pd.DataFrame({
'product': ['Widget', 'Gadget'],
'units_sold': [200, 250],
'region': ['East', 'West']
})
result = pd.concat([df_jan, df_with_extra], join='outer', ignore_index=True)
print(result)Saída:
product units_sold revenue region
0 Widget 150 1500.0 NaN
1 Gadget 200 3000.0 NaN
2 Sprocket 80 960.0 NaN
3 Widget 200 NaN East
4 Gadget 250 NaN WestTodas as colunas de ambos os DataFrames aparecem. Valores ausentes são preenchidos com NaN.
inner join -- Manter apenas colunas compartilhadas
result = pd.concat([df_jan, df_with_extra], join='inner', ignore_index=True)
print(result)Saída:
product units_sold
0 Widget 150
1 Gadget 200
2 Sprocket 80
3 Widget 200
4 Gadget 250Apenas colunas que existem em ambos os DataFrames sobrevivem. A coluna revenue (ausente em df_with_extra) e a coluna region (ausente em df_jan) são ambas removidas.
Quando usar inner join: Quando você quer um resultado limpo sem valores NaN e está disposto a perder colunas que não aparecem em todos os DataFrames.
Concatenando uma lista de DataFrames
Uma das maiores vantagens de pd.concat() sobre outros métodos de combinação é que ele lida com qualquer número de DataFrames em uma única chamada. Este é o padrão standard para combinar arquivos carregados em um loop:
import pandas as pd
# Simulate loading monthly CSV files
months = {
'Jan': {'product': ['Widget', 'Gadget'], 'units': [150, 200]},
'Feb': {'product': ['Widget', 'Gadget'], 'units': [170, 180]},
'Mar': {'product': ['Widget', 'Gadget'], 'units': [190, 210]},
}
dfs = []
for month, data in months.items():
df = pd.DataFrame(data)
df['month'] = month
dfs.append(df)
all_data = pd.concat(dfs, ignore_index=True)
print(all_data)Saída:
product units month
0 Widget 150 Jan
1 Gadget 200 Jan
2 Widget 170 Feb
3 Gadget 180 Feb
4 Widget 190 Mar
5 Gadget 210 MarEste padrão -- construir uma lista de DataFrames e então chamar concat uma vez no final -- é muito mais rápido do que adicionar um DataFrame de cada vez em um loop. Cada append cria uma cópia completa, mas uma única chamada pd.concat() aloca memória uma única vez.
concat vs merge vs append -- Tabela comparativa
O Pandas oferece várias formas de combinar DataFrames. Escolher a correta depende de como você quer combiná-los:
| Característica | pd.concat() | pd.merge() | DataFrame.append() |
|---|---|---|---|
| Uso principal | Empilhar DataFrames (linhas ou colunas) | Juntar por valores de coluna compartilhados (como SQL) | Adicionar linhas a um DataFrame |
| Número de entradas | Qualquer número de uma vez | Dois de cada vez | Dois de cada vez |
| Lógica de correspondência | Alinha por índice (ou nomes de colunas) | Corresponde por valores de coluna chave | Alinha por nomes de colunas |
| Tipos de join | outer, inner | inner, left, right, outer, cross | Apenas outer |
| Comportamento padrão | Outer join, empilhar verticalmente | Inner join em colunas compartilhadas | Outer join, adicionar linhas |
| Melhor para | Combinar arquivos mensais, resultados em lote, tabelas com mesmo esquema | Joins relacionais (clientes + pedidos) | Obsoleto desde pandas 2.0 |
| Desempenho | Rápido para muitos DataFrames | Otimizado para joins de duas tabelas | Lento (copia dados a cada chamada) |
Quando usar cada um
- Use
pd.concat()quando seus DataFrames compartilham a mesma estrutura (mesmas colunas) e você quer empilhá-los. Use-o também para concatenação horizontal ao alinhar por índice. - Use
pd.merge()quando precisar corresponder linhas com base em valores de colunas -- como juntar uma tabela de vendas com uma tabela de produtos porproduct_id. Veja nosso guia de pandas merge para detalhes. - Evite
DataFrame.append()-- foi descontinuado no pandas 1.4 e removido no pandas 2.0. Usepd.concat([df1, df2])em vez disso.
Erros comuns e correções
1. Colunas não se alinham
Ao concatenar DataFrames com nomes de colunas diferentes, o outer join padrão preenche valores ausentes com NaN. Se você não esperava isso, verifique os nomes das suas colunas:
# Diagnose: compare column names
print(df1.columns.tolist())
print(df2.columns.tolist())
# Fix: rename columns to match before concatenating
df2 = df2.rename(columns={'sales': 'revenue', 'qty': 'units_sold'})
combined = pd.concat([df1, df2], ignore_index=True)2. Incompatibilidades de tipo de dados após concatenação
Se um DataFrame armazena uma coluna como int64 e outro como float64, o pandas converte para float. Pior, se um armazena como string, você obtém uma coluna com dtype object:
# Check dtypes after concat
combined = pd.concat([df1, df2], ignore_index=True)
print(combined.dtypes)
# Fix: cast before concatenating
df2['units_sold'] = df2['units_sold'].astype(int)
combined = pd.concat([df1, df2], ignore_index=True)3. Valores de índice duplicados
Sem ignore_index=True, a concatenação vertical preserva os índices originais, levando a valores duplicados. Isso causa problemas com buscas .loc:
combined = pd.concat([df1, df2])
# combined.loc[0] returns TWO rows, not one
# Fix option 1: use ignore_index
combined = pd.concat([df1, df2], ignore_index=True)
# Fix option 2: use verify_integrity to catch the issue early
combined = pd.concat([df1, df2], verify_integrity=True) # raises ValueError4. Concatenação acidental ao longo do eixo errado
Se seu resultado tem o dobro de colunas em vez do dobro de linhas (ou vice-versa), verifique o parâmetro axis:
# Wrong: this adds columns side by side
wrong = pd.concat([df1, df2], axis=1)
# Right: this stacks rows vertically
right = pd.concat([df1, df2], axis=0)Visualize seus DataFrames concatenados com PyGWalker
Após concatenar dados de várias fontes, você frequentemente precisa verificar o resultado e explorar padrões no conjunto de dados combinado. Em vez de escrever código de gráficos manual com 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
# Combine monthly sales data
df_jan = pd.DataFrame({
'product': ['Widget', 'Gadget', 'Sprocket'],
'units_sold': [150, 200, 80],
'revenue': [1500, 3000, 960],
'month': ['Jan', 'Jan', 'Jan']
})
df_feb = pd.DataFrame({
'product': ['Widget', 'Gadget', 'Sprocket'],
'units_sold': [170, 180, 95],
'revenue': [1700, 2700, 1140],
'month': ['Feb', 'Feb', 'Feb']
})
combined = pd.concat([df_jan, df_feb], ignore_index=True)
# Launch interactive visualization
walker = pyg.walk(combined)Com PyGWalker, você pode arrastar product para o eixo x e revenue para o eixo y, e então dividir por month para comparar instantaneamente tendências de receita entre períodos -- sem código de gráficos necessário. Você pode criar gráficos de barras, diagramas de dispersão, gráficos de linhas e mais apenas arrastando campos. É especialmente útil para verificar se sua concatenação funcionou corretamente e se os dados de diferentes fontes se alinham como esperado.
Instale PyGWalker com
pip install pygwalker, ou experimente no Google Colab (opens in a new tab) ou Kaggle (opens in a new tab).
FAQ
Qual é a diferença entre pandas concat e merge?
pd.concat() empilha DataFrames verticalmente (adicionando linhas) ou horizontalmente (adicionando colunas) alinhando pelo índice. pd.merge() junta dois DataFrames correspondendo valores em colunas específicas, como um SQL JOIN. Use concat quando seus DataFrames tiverem as mesmas colunas e você quiser combinar linhas. Use merge quando precisar corresponder linhas com base em uma coluna chave compartilhada.
O pd.concat() modifica os DataFrames originais?
Não. pd.concat() sempre retorna um novo DataFrame. Os DataFrames originais permanecem inalterados. Isso é consistente com o princípio de design do pandas de que operações retornam novos objetos em vez de modificar dados no local.
Como concatenar DataFrames com colunas diferentes?
Use pd.concat() com o padrão join='outer' -- ele mantém todas as colunas de todos os DataFrames e preenche valores ausentes com NaN. Se você quiser apenas colunas que aparecem em todos os DataFrames, defina join='inner'. Você também pode renomear colunas antes de concatenar para garantir o alinhamento.
O pd.concat() é mais rápido que DataFrame.append()?
Sim. DataFrame.append() foi descontinuado no pandas 1.4 e removido no pandas 2.0. Ele chamava pd.concat() internamente, mas criava uma cópia a cada chamada. Ao combinar muitos DataFrames, coletá-los em uma lista e chamar pd.concat() uma vez é significativamente mais rápido porque aloca memória uma única vez.
Como redefinir o índice após a concatenação?
Passe ignore_index=True para pd.concat(): pd.concat([df1, df2], ignore_index=True). Isso substitui os valores de índice originais por um novo índice sequencial começando de 0. Alternativamente, chame .reset_index(drop=True) no resultado.
Conclusão
A função pandas concat() é a ferramenta essencial para combinar DataFrames que compartilham a mesma estrutura. Aqui estão os pontos-chave:
- Concatenação vertical (
axis=0) empilha linhas e é o caso de uso mais comum -- ideal para combinar arquivos mensais, resultados em lote ou conjuntos de dados divididos. - Concatenação horizontal (
axis=1) coloca DataFrames lado a lado, alinhando pelo índice. - Use
ignore_index=Truepara obter um índice sequencial limpo (recomendado na maioria dos casos). - Use
keyspara criar um índice hierárquico que rastreia de qual fonte cada linha veio. - O parâmetro
joincontrola como colunas que não correspondem são tratadas:'outer'mantém tudo,'inner'mantém apenas colunas compartilhadas. - Sempre colete DataFrames em uma lista e chame
pd.concat()uma vez, em vez de adicionar em um loop. - Use
pd.merge()quando precisar de joins estilo SQL em valores de colunas.
Após seus dados serem concatenados, ferramentas como PyGWalker (opens in a new tab) permitem explorar visualmente o resultado combinado sem escrever código de gráficos, tornando mais rápido verificar seu pipeline de dados e descobrir padrões entre fontes.