Skip to content
Tópicos
Pandas
Pandas Concat: How to Concatenate DataFrames in Python

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âmetroDescriçãoPadrão
objsUma lista ou dicionário de DataFrames (ou Series) para concatenarObrigatório
axis0 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_indexSe True, redefine o índice para 0, 1, 2, ... no resultadoFalse
keysRótulos para identificar de qual DataFrame original cada linha veioNone
sortOrdenar eixo de não concatenação (nomes de colunas para axis=0)False
verify_integrityLevantar erro se o resultado tiver valores de índice duplicadosFalse

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     1140

Concatenando 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     1140

Observe 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     1140

Quando 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     1140

Você 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      960

Quando 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            1080

Isso 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.0

A 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   West

Todas 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         250

Apenas 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   Mar

Este 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ísticapd.concat()pd.merge()DataFrame.append()
Uso principalEmpilhar DataFrames (linhas ou colunas)Juntar por valores de coluna compartilhados (como SQL)Adicionar linhas a um DataFrame
Número de entradasQualquer número de uma vezDois de cada vezDois de cada vez
Lógica de correspondênciaAlinha por índice (ou nomes de colunas)Corresponde por valores de coluna chaveAlinha por nomes de colunas
Tipos de joinouter, innerinner, left, right, outer, crossApenas outer
Comportamento padrãoOuter join, empilhar verticalmenteInner join em colunas compartilhadasOuter join, adicionar linhas
Melhor paraCombinar arquivos mensais, resultados em lote, tabelas com mesmo esquemaJoins relacionais (clientes + pedidos)Obsoleto desde pandas 2.0
DesempenhoRápido para muitos DataFramesOtimizado para joins de duas tabelasLento (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 por product_id. Veja nosso guia de pandas merge para detalhes.
  • Evite DataFrame.append() -- foi descontinuado no pandas 1.4 e removido no pandas 2.0. Use pd.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 ValueError

4. 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=True para obter um índice sequencial limpo (recomendado na maioria dos casos).
  • Use keys para criar um índice hierárquico que rastreia de qual fonte cada linha veio.
  • O parâmetro join controla 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.

📚