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().