Python Pandas: How to Fix "TypeError: first argument must be an iterable of pandas objects" (pd.concat)
The TypeError: first argument must be an iterable of pandas objects, you passed an object of type "DataFrame"
is a common error when using the pandas.concat()
function. It indicates that you've provided a single Pandas object (like a DataFrame or Series) directly as the first argument, whereas pd.concat()
expects a collection (an iterable, typically a list) of Pandas objects to join together.
This guide explains the error and shows the correct way to use pd.concat()
.
Understanding the Error: Iterable Expected
The pandas.concat()
function is designed to combine multiple Pandas DataFrames or Series along a particular axis. Its first argument, objs
, must be a sequence (like a list or tuple) containing the Pandas objects you wish to concatenate. The error message "first argument must be an iterable of pandas objects" clearly states this requirement. Passing a single DataFrame directly violates this expectation.
The Cause: Passing a Single DataFrame (or Series)
The error occurs when you incorrectly call pd.concat()
by passing a single DataFrame object as the first argument, instead of a list containing that DataFrame (or multiple DataFrames).
import pandas as pd
df1 = pd.DataFrame({
'letter': ['A', 'B'],
'number': [1, 2]
})
# df2 is created just for context, but the error is with df1's usage
df2 = pd.DataFrame({
'letter': ['C', 'D'],
'number': [3, 4]
})
try:
# ⛔️ Incorrect: Passing a single DataFrame object directly
df_combined_error = pd.concat(df1)
print(df_combined_error)
except TypeError as e:
print(f"Error: {e}")
Output:
Even if your intention is to concatenate df1
with other DataFrames later, or if you are building the list of DataFrames dynamically and accidentally pass a single one, pd.concat()
requires that single DataFrame to be within a list.
The Solution: Pass a List of DataFrames (or Series)
To fix this error, ensure that the first argument to pd.concat()
is a list (or another iterable like a tuple) containing the DataFrame(s) you want to concatenate.
import pandas as pd
df1 = pd.DataFrame({
'letter': ['A', 'B'],
'number': [1, 2]
})
df2 = pd.DataFrame({
'letter': ['C', 'D'],
'number': [3, 4]
})
df_another = pd.DataFrame({ # For an example with more than two
'letter': ['E'],
'number': [5]
})
# ✅ Correct: Pass a list of DataFrames
df_combined_correct = pd.concat([df1, df2])
print("Concatenating two DataFrames:")
print(df_combined_correct)
print()
# ✅ Correct: List can contain one or more DataFrames
df_combined_multiple = pd.concat([df1, df2, df_another])
print("Concatenating multiple DataFrames:")
print(df_combined_multiple)
Output:
Concatenating two DataFrames:
letter number
0 A 1
1 B 2
0 C 3
1 D 4
Concatenating multiple DataFrames:
letter number
0 A 1
1 B 2
0 C 3
1 D 4
0 E 5
Important: Do not pass DataFrames as separate arguments like pd.concat(df1, df2)
. They must be grouped into a single iterable: pd.concat([df1, df2])
.
Using ignore_index=True
for a Clean Index
When you concatenate DataFrames, the original indices are preserved by default, which can lead to duplicate index labels in the resulting DataFrame (as seen in the output above: 0, 1, 0, 1, ...
). To create a new, continuous index from 0
to n-1
, set the ignore_index=True
parameter.
import pandas as pd
df1 = pd.DataFrame({
'letter': ['A', 'B'],
'number': [1, 2]
})
df2 = pd.DataFrame({
'letter': ['C', 'D'],
'number': [3, 4]
})
# ✅ Concatenate with ignore_index=True
df_combined_reset_index = pd.concat([df1, df2], ignore_index=True)
print(df_combined_reset_index)
Output:
letter number
0 A 1
1 B 2
2 C 3
3 D 4
Now the index is 0, 1, 2, 3
, which is often the desired behavior.
Concatenating Pandas Series
The same principle applies when concatenating Pandas Series objects. You must pass a list of Series to pd.concat()
.
Concatenating Series into a Single Series
By default (with axis=0
), pd.concat()
will append Series objects end-to-end, resulting in a new, longer Series.
import pandas as pd
s1 = pd.Series(['A', 'B'], name='col1')
s2 = pd.Series(['C', 'D'], name='col1') # Same name is fine for Series concat
# ✅ Pass a list of Series
s_combined = pd.concat([s1, s2], ignore_index=True)
print(s_combined)
Output:
0 A
1 B
2 C
3 D
Name: col1, dtype: object
Concatenating Series into a DataFrame (using axis=1
)
If you want to combine Series objects as columns in a new DataFrame, you need to specify axis=1
.
import pandas as pd
s1 = pd.Series(['A', 'B'], name='column_alpha') # Names help define column headers
s2 = pd.Series(['C', 'D'], name='column_beta')
# ✅ Concatenate Series along columns (axis=1)
df_from_series = pd.concat([s1, s2], axis=1)
print(df_from_series)
Output:
column_alpha column_beta
0 A C
1 B D
axis=0
(default): Concatenates along the rows (index).axis=1
: Concatenates along the columns.
Conclusion
The TypeError: first argument must be an iterable of pandas objects
in pandas.concat()
is a clear indication that you've passed a single DataFrame or Series where a list (or other iterable) of these objects was expected.
- The solution is consistently to wrap your Pandas objects in a list (e.g.,
pd.concat([df1, df2])
instead ofpd.concat(df1)
orpd.concat(df1, df2)
). - Remember to use
ignore_index=True
for a fresh index andaxis=1
when combining Series as new columns in a DataFrame.