pandas
data manipulation
duplicate indices
python programming
data cleaning

Remove pandas rows with duplicate indices

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

Duplicate index labels in pandas can break assumptions in joins, reindexing, and lookups. Even when data values are correct, repeated index entries can cause ambiguous results and difficult debugging. This guide shows reliable ways to detect, remove, or aggregate duplicate indices depending on what your pipeline needs.

Detect Duplicate Index Labels

Start by checking whether duplicates exist and where they occur.

python
1import pandas as pd
2
3df = pd.DataFrame(
4    {
5        "city": ["Toronto", "Montreal", "Ottawa", "Calgary"],
6        "temp": [20, 22, 19, 17],
7    },
8    index=["day1", "day1", "day2", "day3"],
9)
10
11print(df.index.duplicated())
12print(df[df.index.duplicated(keep=False)])

index.duplicated() returns a boolean mask. Using keep=False marks all duplicates, which is useful for audits before cleanup.

Remove Duplicate Indices and Keep First or Last

If you only want one row per index label, filter with the duplicated mask.

python
1# Keep first occurrence
2clean_first = df[~df.index.duplicated(keep="first")]
3print(clean_first)
4
5# Keep last occurrence
6clean_last = df[~df.index.duplicated(keep="last")]
7print(clean_last)

This is the most common fix for logs or event streams where repeated index labels are expected but only one record should survive.

To drop all labels that appear more than once, use:

python
only_unique = df[~df.index.duplicated(keep=False)]
print(only_unique)

That pattern keeps only truly unique index labels and removes every duplicated group.

Aggregate Duplicate Indices Instead of Dropping Rows

In analytics pipelines, dropping rows may lose signal. Aggregation can preserve information while enforcing unique indices.

python
1agg = df.groupby(level=0).agg(
2    {
3        "city": "first",
4        "temp": "mean",
5    }
6)
7print(agg)

groupby(level=0) groups by the index. You can pick aggregation per column, such as sum, mean, max, or custom functions.

For deterministic output, sort index after aggregation:

python
agg = agg.sort_index()

This helps when downstream tests compare exact DataFrame snapshots.

Reset and Rebuild Index When Needed

Sometimes duplicate labels indicate that the chosen index is wrong for the task. Resetting index can be cleaner than patching duplicates repeatedly.

python
1reset = df.reset_index(names="event_id")
2print(reset)
3
4# Build a new unique index from a stable column
5reset["row_id"] = range(1, len(reset) + 1)
6reindexed = reset.set_index("row_id")
7print(reindexed)

This approach is useful before merges where a guaranteed unique key is required.

Validate Uniqueness in Data Pipelines

Add assertions after critical transforms so duplicate indices are caught early.

python
1def assert_unique_index(frame: pd.DataFrame) -> None:
2    if not frame.index.is_unique:
3        dupes = frame.index[frame.index.duplicated()].unique().tolist()
4        raise ValueError(f"Duplicate index labels found: {dupes}")
5
6
7assert_unique_index(clean_first)

Early validation prevents silent downstream misalignment.

Preserve Duplicate Records for Audit Needs

Sometimes duplicates should be reviewed rather than discarded. Mark and split them into separate outputs.

python
1audit = df.copy()
2audit["is_duplicate_index"] = audit.index.duplicated(keep=False)
3
4duplicates_only = audit[audit["is_duplicate_index"]]
5clean_primary = audit[~audit.index.duplicated(keep="first")]
6
7print("duplicates")
8print(duplicates_only)
9print("clean")
10print(clean_primary)

This approach keeps an auditable trail while still producing a unique-index dataset for downstream processing.

If your pipeline writes both outputs, store the duplicate report with run metadata such as source file and execution timestamp so analysts can trace why specific records were retained or dropped.

Common Pitfalls

A common mistake is removing duplicates without confirming business intent. Keeping first or last may hide important updates if event order is not reliable.

Another issue is assuming index uniqueness after concatenation. concat can create duplicates when source frames share index labels. Validate after combine steps.

Developers also forget that index type matters. String labels like "01" and integer labels like 1 are different values, so cleanup logic should match expected index dtype.

Summary

  • Use index.duplicated() to detect and inspect duplicate labels quickly.
  • Keep first, keep last, or remove all duplicates based on data requirements.
  • Prefer aggregation when duplicate rows contain useful information.
  • Reset and rebuild index when current labels are not suitable identifiers.
  • Add explicit uniqueness checks in pipelines to catch regressions early.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

All Rights Reserved.