Fix pandas AttributeError: 'DataFrame' object has no attribute 'iteritems'

Fix pandas AttributeError: 'DataFrame' object has no attribute 'iteritems'

You upgraded pandas — or cloned a project that uses a newer version — and now existing code raises:

AttributeError: 'DataFrame' object has no attribute 'iteritems'

Or on a Series:

AttributeError: 'Series' object has no attribute 'iteritems'

This error means you are running pandas 2.0 or later against code written for pandas 1.x. The .iteritems() method was deprecated in pandas 1.5 (August 2022) and completely removed in pandas 2.0 (April 2023). The fix is a one-character change, but the same pandas 2.0 release removed several other APIs that may be lurking in the same codebase.


The Error and Which pandas Version Removed It

pandas 2.0 was released in April 2023 and is the first major version with breaking API removals that had been deprecated for years. The full traceback when calling .iteritems() looks like this:

Traceback (most recent call last):
  File "process_data.py", line 14, in <module>
    for col_name, col_data in df.iteritems():
  File "/usr/local/lib/python3.11/site-packages/pandas/core/generic.py", line 6299, in __getattr__
    return object.__getattribute__(self, name)
AttributeError: 'DataFrame' object has no attribute 'iteritems'. Did you mean: 'itertuples'?

The "Did you mean: 'itertuples'?" suggestion is not the right fix — itertuples() iterates over rows, not columns. The correct replacement is .items().

import pandas as pd

# Check your pandas version
print(pd.__version__)
# 2.x.x → iteritems() is gone
# 1.5.x → iteritems() still works but shows FutureWarning
# 1.4.x → iteritems() works silently

# Reproduce the error (pandas >= 2.0)
df = pd.DataFrame({
    'temperature': [22.1, 19.8, 25.3],
    'humidity':    [0.55, 0.72, 0.41],
    'pressure':    [1013, 1009, 1017]
})

# This raises AttributeError on pandas >= 2.0
for col_name, col_data in df.iteritems():
    print(col_name, col_data.mean())

Fix: Replace .iteritems() with .items()

.items() is the direct replacement for .iteritems() on both DataFrame and Series. It has the identical signature, return type, and behavior. The only difference is the name.

On a DataFrame

import pandas as pd

df = pd.DataFrame({
    'temperature': [22.1, 19.8, 25.3],
    'humidity':    [0.55, 0.72, 0.41],
    'pressure':    [1013, 1009, 1017]
})

# Before (pandas 1.x) — raises AttributeError on pandas 2.0+
# for col_name, col_data in df.iteritems():
#     print(col_name, col_data.mean())

# After (works on all pandas versions including 2.0+)
for col_name, col_data in df.items():
    print(f"{col_name}: mean={col_data.mean():.2f}")

# Output:
# temperature: mean=22.40
# humidity: mean=0.56
# pressure: mean=1013.00

On a Series

import pandas as pd

s = pd.Series({'a': 10, 'b': 20, 'c': 30})

# Before (pandas 1.x)
# for idx, val in s.iteritems():
#     print(idx, val)

# After (pandas 2.0+)
for idx, val in s.items():
    print(idx, val)

# a 10
# b 20
# c 30

The items() method on a DataFrame yields (column_name, Series) pairs — the same as before. The items() method on a Series yields (index_label, value) pairs — also the same as before. This is a pure rename with no behavioral change.

Codebase-Wide Find and Replace

# Quick audit from Python to find all occurrences before changing them
import subprocess
result = subprocess.run(
    ['grep', '-rn', r'\.iteritems()', '.', '--include=*.py'],
    capture_output=True, text=True
)
print(result.stdout)
# ./analysis/process_data.py:14:    for col_name, col_data in df.iteritems():
# ./utils/helpers.py:87:        for k, v in series.iteritems():
# Bash one-liner to replace across all Python files in the project
find . -name "*.py" -exec sed -i 's/\.iteritems()/.items()/g' {} +

# Verify no occurrences remain
grep -rn '\.iteritems()' . --include='*.py'

The replacement is safe to do blindly — .items() was available on DataFrame and Series since pandas 0.24 (2019), so the renamed version works on all supported versions.


Other pandas 2.0 Removed APIs

If you are migrating a codebase from pandas 1.x to 2.x, iteritems() is usually not the only thing that breaks. These APIs were also removed in pandas 2.0:

DataFrame.append() is gone — use pd.concat()

import pandas as pd

df1 = pd.DataFrame({'a': [1, 2], 'b': [3, 4]})
df2 = pd.DataFrame({'a': [5, 6], 'b': [7, 8]})

# Before (pandas 1.x) — AttributeError on pandas 2.0+
# combined = df1.append(df2, ignore_index=True)

# After
combined = pd.concat([df1, df2], ignore_index=True)
print(combined)
#    a  b
# 0  1  3
# 1  2  4
# 2  5  7
# 3  6  8

bool() on a Series raises an error — use .any() or .all()

import pandas as pd

s = pd.Series([True, False, True])

# Before (pandas 1.x, ambiguous but worked for length-1 Series)
# if bool(s):  # raises ValueError in pandas 2.0 for len > 1

# The correct way — always was, now enforced
if s.any():
    print("At least one True")

if s.all():
    print("All True")

# For a single-element comparison result:
value = pd.Series([42])
if (value > 10).item():   # .item() extracts the scalar
    print("Greater than 10")

Chained assignment now raises an error — use .loc[]

import pandas as pd

df = pd.DataFrame({'category': ['A', 'B', 'A'], 'value': [10, 20, 30]})

# Before (pandas 1.x) — chained indexing, raised SettingWithCopyWarning
# df[df['category'] == 'A']['value'] = 99  # often silently failed

# After — pandas 2.0 enforces Copy-on-Write (CoW), this no longer modifies df
# Use .loc[] instead:
df.loc[df['category'] == 'A', 'value'] = 99
print(df)
#   category  value
# 0        A     99
# 1        B     20
# 2        A     99

Numeric-only default removed from DataFrame.mean() and related

import pandas as pd

df = pd.DataFrame({'a': [1, 2, 3], 'b': ['x', 'y', 'z'], 'c': [4.0, 5.0, 6.0]})

# Before (pandas 1.x) — silently skipped non-numeric columns
# df.mean()  # returned mean of 'a' and 'c' only

# After (pandas 2.0) — must specify numeric_only explicitly
print(df.mean(numeric_only=True))
# a    2.0
# c    5.0
# dtype: float64

How to Check Your pandas Version and Audit Dependencies

import pandas as pd

# Runtime version
print(pd.__version__)

# Check against a version floor
from packaging.version import Version
if Version(pd.__version__) < Version("2.0.0"):
    print("Running pandas 1.x — iteritems() available")
else:
    print("Running pandas 2.x — use .items() instead")
# Check what version is installed
pip show pandas

# Pin a safe version if you cannot upgrade all code yet
pip install "pandas>=1.5,<2.0"

# Or upgrade to 2.x and fix the code
pip install --upgrade pandas

If you maintain a library or package, add a pandas version floor to your requirements.txt or pyproject.toml so users get a clear error at install time rather than a runtime AttributeError:

# requirements.txt
pandas>=2.0.0
# pyproject.toml
[project]
dependencies = [
    "pandas>=2.0.0",
]

The FutureWarning You Should Have Caught Earlier

If you had been running pandas 1.5.x, every call to .iteritems() would have shown:

FutureWarning: DataFrame.iteritems is deprecated. Use DataFrame.items instead.

pandas 1.5 was released in August 2022, giving eight months of warning before the 2.0 removal. The lesson for any production codebase: run your test suite against the current version with deprecation warnings enabled and treat FutureWarning from major library dependencies as technical debt to clear before the next major version ships.

import warnings
import pandas as pd

# Treat FutureWarnings from pandas as errors during development
# so they surface in CI before they become AttributeErrors
warnings.filterwarnings("error", category=FutureWarning, module="pandas")

df = pd.DataFrame({'a': [1, 2, 3]})

# On pandas 1.5.x this now raises FutureWarning as an error,
# forcing you to fix it before upgrading to 2.0
for col, data in df.iteritems():   # raises FutureWarning -> treated as error
    print(col, data.mean())

Add this warnings.filterwarnings call to your test configuration (e.g., conftest.py in pytest) so deprecation warnings from any library surface during CI before they become production errors.


Quick Reference

  • Root cause: pandas 2.0 (April 2023) removed .iteritems() after deprecating it in pandas 1.5.
  • Fix: replace .iteritems() with .items() everywhere — same signature, same return type.
  • Other removed APIs: DataFrame.append()pd.concat(); bool(Series).any()/.all(); chained assignment silently fails under CoW.
  • Forward-proof: enable FutureWarning as errors in CI so the next deprecation wave surfaces before it breaks production.

Related articles