Interview Q&A / Data Science

BeginnerIn-depth3 min readUpdated 2 Oct 2026

What is the difference between merge, join and concat in pandas?

SHORT ANSWER

merge combines two DataFrames on matching column values, like a SQL join. join does the same but matches on the index by default. concat simply stacks DataFrames on top of each other (rows) or side by side (columns) without matching any keys.

Explain it simply

Think of two registers kept by a college office. One has roll numbers and names. The other has roll numbers and maths marks.

  • merge is matching the two registers by roll number, so each student's name sits next to their marks.
  • join is the same matching, but it uses the row labels (the index) instead of a column.
  • concat is stapling the Section B register under the Section A register. Nothing is matched; the pages are just put together.

Example

python
import pandas as pd

students = pd.DataFrame({"roll": [1, 2, 3], "name": ["Asha", "Ravi", "Meena"]})
marks = pd.DataFrame({"roll": [1, 2, 4], "maths": [88, 72, 95]})

# merge: match on a column (inner join by default)
print(pd.merge(students, marks, on="roll"))
#    roll  name  maths
# 0     1  Asha     88
# 1     2  Ravi     72

# merge with how="left": keep every student
print(pd.merge(students, marks, on="roll", how="left"))
#    roll   name  maths
# 0     1   Asha   88.0
# 1     2   Ravi   72.0
# 2     3  Meena    NaN

# join: match on the index (left join by default)
print(students.set_index("roll").join(marks.set_index("roll")))
#        name  maths
# roll
# 1      Asha   88.0
# 2      Ravi   72.0
# 3     Meena    NaN

# concat: stack rows, no matching
sec_b = pd.DataFrame({"roll": [4, 5], "name": ["Imran", "Divya"]})
print(pd.concat([students, sec_b], ignore_index=True))
#    roll   name
# 0     1   Asha
# 1     2   Ravi
# 2     3  Meena
# 3     4  Imran
# 4     5  Divya

Notice two details. Roll 4 has marks but no name, so the inner merge drops it. And maths turns into floats (88.0) in the left join, because pandas needs NaN for Meena and NaN is a float.

How it works

pd.merge(left, right, on=..., how=...)

  • Matches rows where key columns are equal.
  • how can be "inner" (default), "left", "right", "outer" or "cross", just like SQL.
  • Use left_on and right_on when the key columns have different names.

left.join(right, how=...)

  • A shortcut for merging on the index. Default is a left join.
  • Handy when your data is already indexed by an ID or a date.

pd.concat([df1, df2], axis=0 or 1)

  • axis=0 (default) stacks rows. Columns are aligned by name; a missing column becomes NaN.
  • axis=1 places frames side by side, aligned by index.
  • ignore_index=True gives a fresh 0, 1, 2... index instead of repeating the old ones.

Real-world use

  • merge: joining an orders table with a customers table on customer_id.
  • join: combining several daily price series that are all indexed by date.
  • concat: reading 12 monthly CSV files and stacking them into one year of data.

Common mistakes

  • Using concat when you meant to match on a key. Rows will line up by position or index, not by ID, and the result will be silently wrong.
  • Merging on a key that has duplicates on both sides. Every match pairs up, so rows multiply. Use validate="one_to_one" or "many_to_one" to catch this.
  • Forgetting the default is an inner merge and losing rows without noticing. Compare row counts before and after.
  • Overlapping column names get suffixes _x and _y. Set suffixes= to readable names.

What to say in the interview

"merge is pandas' SQL-style join: it matches rows on one or more key columns, and I choose inner, left, right or outer with the how parameter. join is a convenience method that matches on the index and defaults to a left join. concat does no matching at all; it stacks DataFrames vertically or horizontally. So if I need to combine tables by an ID I use merge, and if I am appending monthly files with the same columns I use concat."

Follow-up questions

  • What happens when the merge key has duplicate values in both DataFrames?
  • How would you find rows that exist in one DataFrame but not the other? (Hint: indicator=True.)
  • What is the difference between concat with axis=0 and axis=1?
  • Why did the integer column become float after a left merge?

#pandas#python#data-wrangling#joins

Related questions

Practise more Data Science questions

Test your recall with short answers, then return to the detailed explanations when you need context.

Open Data Science quick answers →

Get new questions like this by email

One short email when something new and useful lands. No spam, unsubscribe in one tap.

By subscribing you agree to the Privacy Policy.