pandas pivot: Index contains duplicate entries, cannot reshape (tested)

ValueError: Index contains duplicate entries, cannot reshape from df.pivot() means some (index, columns) pair appears in more than one row. pivot cannot combine them; use pivot_table with an explicit aggfunc, or drop the duplicates first. Tested on pandas 2.3.3 and 3.1.0.

1. Reproduce it

import pandas as pd
df = pd.DataFrame({
    "date":  ["2026-01-01", "2026-01-01", "2026-01-01", "2026-01-02"],
    "store": ["A", "A", "B", "A"],
    "sales": [10, 5, 7, 3],
})
try:
    df.pivot(index="date", columns="store", values="sales")
except ValueError as e:
    print("ValueError:", e)

Output, identical on pandas 2.3.3 and 3.1.0:

ValueError: Index contains duplicate entries, cannot reshape

pivot() only reshapes; it never combines values. Each (index, columns) pair must appear once, because it becomes exactly one cell. Here ("2026-01-01", "A") appears twice (10 and 5), so pandas cannot decide which to put in the cell. The "Index" in the message means that pair, not your DataFrame index, so df.index.is_unique being True does not help.

2. Find the duplicates, then aggregate them

import pandas as pd
df = pd.DataFrame({
    "date":  ["2026-01-01", "2026-01-01", "2026-01-01", "2026-01-02"],
    "store": ["A", "A", "B", "A"],
    "sales": [10, 5, 7, 3],
})
# 1. find the rows that collide
dupes = df[df.duplicated(["date", "store"], keep=False)]
print(dupes)
# 2. aggregate them: pivot_table (default aggfunc is mean)
print(df.pivot_table(index="date", columns="store", values="sales", aggfunc="sum"))
# 3. same result with groupby + unstack
print(df.groupby(["date", "store"])["sales"].sum().unstack())

Output, identical on pandas 2.3.3 and 3.1.0:

         date store  sales
0  2026-01-01     A     10
1  2026-01-01     A      5
store          A    B
date                 
2026-01-01  15.0  7.0
2026-01-02   3.0  NaN
store          A    B
date                 
2026-01-01  15.0  7.0
2026-01-02   3.0  NaN

duplicated(..., keep=False) lists every colliding row so you can check whether they are real repeats (sum them) or bad data (drop them with drop_duplicates(["date", "store"]) and then pivot works). pivot_table with no aggfunc uses the mean: on this data the A cell becomes 7.5, not 15, which is easy to miss. Add fill_value=0 to get 0 instead of NaN for missing pairs; the columns then stay integers (15, 7, 3, 0).

3. Other pivot errors

import pandas as pd
df = pd.DataFrame({"date": ["d1", "d2"], "store": ["A", "B"], "sales": [1, 2]})
try:
    df.pivot(index="Date", columns="store", values="sales")
except KeyError as e:
    print("KeyError:", e)
try:
    df.pivot("date", "store", "sales")
except TypeError as e:
    print("TypeError:", e)

Output with pandas 2.3.3:

KeyError: 'Date'
TypeError: DataFrame.pivot() takes 1 positional argument but 4 were given

Output with pandas 3.1.0:

KeyError: "The following 'index' labels are not columns of the DataFrame: ['Date']"
TypeError: DataFrame.pivot() takes 1 positional argument but 4 were given

A misspelled column (here Date vs date) gives a bare KeyError on pandas 2; pandas 3 names the argument. Since pandas 2.0, index, columns and values must be passed as keywords; old tutorials that call df.pivot("date", "store", "sales") now raise TypeError.

Related: KeyError but the column exists · groupby FutureWarnings · merge KeyError / not matching.

Frequently asked questions

What does Index contains duplicate entries, cannot reshape mean?

Two or more rows share the same value in the index column and the columns column, so pivot would need to put two values in one cell.

What is the difference between pivot and pivot_table?

pivot only reshapes and fails on duplicate pairs. pivot_table aggregates duplicates, using the mean by default unless you pass aggfunc.

Why does df.pivot('a', 'b', 'c') raise TypeError?

Since pandas 2.0 pivot takes keyword arguments only: df.pivot(index='a', columns='b', values='c').

Written with AI assistance. Measured on 2026-10-23 in the python:3-alpine Docker image (Python 3.14.7) with pandas 2.3.3 and pandas 3.1.0. Outputs pasted unedited. PlainTables is our extension; Python and pandas are free.