data frames
data comparison
pandas
python
data analysis

Find difference between two data frames

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

Finding the difference between two pandas DataFrames can mean several different things: checking whether they are exactly equal, locating changed cell values, or identifying rows that exist in one table but not the other. The right method depends on which kind of difference you care about, so the first step is to define the comparison precisely.

Exact Equality Is the Simplest Check

If you only need to know whether two DataFrames are identical in values, index, and column order, use equals().

python
1import pandas as pd
2
3df1 = pd.DataFrame({"id": [1, 2], "value": [10, 20]})
4df2 = pd.DataFrame({"id": [1, 2], "value": [10, 20]})
5
6print(df1.equals(df2))

This returns one boolean, which is useful for quick assertions but not for understanding where the data differs.

Use compare() for Cell-Level Differences

If the DataFrames have the same index and columns and you want to see changed cells, compare() is the most direct tool.

python
1import pandas as pd
2
3df1 = pd.DataFrame({"id": [1, 2], "value": [10, 20]})
4df2 = pd.DataFrame({"id": [1, 2], "value": [10, 25]})
5
6print(df1.compare(df2))

The output highlights the old and new values side by side. This is ideal when both tables represent the same shape and identity, and only the contents may have changed.

Align First if Shape or Ordering Differs

Many comparison bugs come from comparing frames that are logically the same table but are ordered differently. Before comparing, sort or align them on stable keys.

python
1import pandas as pd
2
3df1 = pd.DataFrame({"id": [2, 1], "value": [20, 10]}).sort_values("id").reset_index(drop=True)
4df2 = pd.DataFrame({"id": [1, 2], "value": [10, 25]}).sort_values("id").reset_index(drop=True)
5
6print(df1.compare(df2))

Without alignment, you may report differences that are really just row-order differences.

Find Added or Removed Rows With merge

If you want to know which rows appear in one DataFrame but not the other, use an outer merge with the indicator column.

python
1import pandas as pd
2
3left = pd.DataFrame({"id": [1, 2, 3], "value": [10, 20, 30]})
4right = pd.DataFrame({"id": [2, 3, 4], "value": [20, 35, 40]})
5
6merged = left.merge(right, how="outer", indicator=True)
7print(merged)

The _merge column tells you whether each row came from:

  • 'left_only'
  • 'right_only'
  • 'both'

This is often the right answer when the task is really about row presence rather than cell-by-cell changes.

Compare Specific Columns or Keys When Full Equality Is Too Strict

Sometimes only a subset of columns matters. In that case, reduce the DataFrames before comparison.

python
important1 = df1[["id", "value"]]
important2 = df2[["id", "value"]]
print(important1.compare(important2))

This keeps the comparison tied to the business rule instead of accidentally treating metadata columns as important changes.

Missing Values Need Intentional Handling

NaN handling can affect the result. Depending on the method and the shape of the inputs, missing values may be treated as equal in some contexts and as differences in others.

If missing values have a business meaning, normalize them before comparison.

python
df1 = df1.fillna("MISSING")
df2 = df2.fillna("MISSING")

Do not let null semantics remain implicit if the comparison result will drive data validation or alerts.

Common Pitfalls

The most common mistake is comparing two DataFrames without first aligning them by key and order.

Another mistake is using equals() when the real requirement is to identify which cells or rows changed.

A third issue is comparing whole tables when only a subset of columns matters to the business logic.

Finally, missing values, duplicate keys, and row-order differences can all make a naive comparison look more dramatic than the actual data change.

Summary

  • Use equals() for a strict yes-or-no equality check.
  • Use compare() when the shape matches and you want changed cell values.
  • Align or sort by stable keys before comparing.
  • Use outer merge(..., indicator=True) to find added or removed rows.
  • Limit the comparison to relevant columns when full-table equality is too strict.
  • Define how missing values should be treated before trusting the diff.

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.