HOWTO · Pandas

How to Concatenate Two DataFrames in Pandas Python

With the help of Pandas, it is possible to quickly combine series or dataframe with different types of set logic for the indexes and relational algebra capabilities for join and merge-type operations.

On this page

Combine two Pandas DataFrame objects with pd.concat([df1, df2]). By default, this stacks their rows and keeps their original index labels. Use axis=1 to place columns side by side, where Pandas aligns rows by index. If rows should match by a shared column such as id, use DataFrame.merge() with that column as the key.

The examples below use small, explicit inputs so you can adapt the operation to your own columns and index. Each output shows the result for its corresponding example.

Concatenate Two DataFrames in Pandas Python

A Pandas DataFrame is a labeled table with columns that can hold different kinds of values. When two tables contain the same kinds of records, row concatenation is a direct way to combine them. Pass the frames in the desired order as a list to pd.concat():

import pandas as pd

df1 = pd.DataFrame({"id": [1, 2], "name": ["Ada", "Lin"]})
df2 = pd.DataFrame({"id": [3, 4], "name": ["Sam", "Mina"]})

combined = pd.concat([df1, df2])
print(combined)
   id  name
0   1   Ada
1   2   Lin
0   3   Sam
1   4  Mina

The default is axis=0, so rows from df2 follow rows from df1. The original index labels are retained; because both inputs start at index 0, the combined result has repeated index labels. If a fresh sequential index is more useful, pass ignore_index=True: pd.concat([df1, df2], ignore_index=True). This changes the result’s index, while leaving the values and row order intact.

Use concat() to Concatenate DataFrames Along Rows or Columns

The axis argument selects the direction of concatenation. axis=0 adds rows, which is the default. axis=1 adds columns and aligns each input by its index labels. For example, rows with the same index appear together; rows without a matching label are still represented, with a missing value in the other frame’s columns.

import pandas as pd

names = pd.DataFrame({"name": ["Ada", "Lin"]}, index=[10, 20])
scores = pd.DataFrame({"score": [91, 84]}, index=[10, 20])

side_by_side = pd.concat([names, scores], axis=1)
print(side_by_side)
   name  score
10  Ada     91
20  Lin     84

Choose the axis from the shape of the result you need: stacking records uses rows, and adding fields uses columns. The join argument to concat() describes how to align labels on the other axis. It does not compare values in a column such as id; for that task, use a key-based merge in the next section.

Align DataFrames by Index or Join Them by a Shared Key

Side-by-side concatenation matches index labels, not equal values in a data column. join="outer" is the default alignment for the other axis and keeps labels found in either input, filling unmatched cells with missing values. join="inner" keeps only labels present in both inputs. Inner alignment can discard rows, so choose it only when limiting the result to shared labels is intended.

import pandas as pd

left = pd.DataFrame({"name": ["Ada", "Lin"]}, index=[1, 2])
right = pd.DataFrame({"score": [91, 84]}, index=[2, 3])

outer = pd.concat([left, right], axis=1, join="outer")
inner = pd.concat([left, right], axis=1, join="inner")
print("outer rows:", len(outer), "inner rows:", len(inner))
outer rows: 3 inner rows: 1

To match records using a shared field, use merge() and name the key with on. This operation matches equal key values even if the two tables use different row indexes. The example below keeps only IDs present in both inputs; use how="left", "right", or "outer" when you need a different set of keys.

import pandas as pd

people = pd.DataFrame({"id": [1, 2], "name": ["Ada", "Lin"]})
results = pd.DataFrame({"id": [2, 3], "score": [84, 91]})

matched = people.merge(results, on="id", how="inner")
print(matched)
   id name  score
0   2  Lin     84

Replace Deprecated append() with concat()

Older examples may use the append() method to add one frame’s rows to another. For this task, write the operation with concat() and pass both frames in order. This makes the row-wise combination explicit and follows the same pattern as the main example:

import pandas as pd

first = pd.DataFrame({"item": ["pen", "book"]})
second = pd.DataFrame({"item": ["lamp"]})

combined = pd.concat([first, second], ignore_index=True)
print(combined)
   item
0   pen
1  book
2  lamp

The ignore_index=True option is useful when the source index labels are not meaningful in the combined table. Omit it when those labels carry information you need to preserve. No version-specific execution evidence is available, so this section makes no claim about which Pandas versions provide append().