Pandas idxmax & idxmin
max() tells you the biggest number in a column. It does not tell you who it belongs to. idxmax() answers that second question — it returns the index label of the row holding that maximum, which you can hand straight to .loc to pull back the whole record.
idxmax() returns the index label of the largest value, not the value itself. Pull the whole row with df.loc[], get the top row per group, and avoid the…
Part of the free Pandas course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
This is the everyday "which product sold most?" question, and getting it wrong — by sorting the entire frame, or by confusing idxmax with argmax — is one of the most common beginner mistakes in pandas.
What You'll Learn in This Lesson
1 The Value vs. the Location
These two methods answer different questions, and mixing them up is where the confusion starts:
- df["sales"].max() — what is the largest number? → 980
- df["sales"].idxmax() — where is it? → 2 (an index label)
On its own that label is not very interesting. Its power is that .loc accepts it, so the two together give you the complete winning row:
idxmin() is the exact mirror image and takes all the same arguments, so everything below applies to finding minimums too.
2 idxmax vs. argmax — the Bug That Hides
argmax() returns the position (0, 1, 2 …). idxmax() returns the label . On a fresh DataFrame these are the same number, so code using the wrong one appears to work — until you filter the rows or set a custom index, and the labels stop matching the positions.
After a filter, the surviving rows keep their original labels — so a frame of three rows might have labels 1, 2 and 5. That is exactly when position and label part company.
3 The Best Row in Every Group
This is where idxmax really earns its place. Suppose you want the top-selling product per region . A plain groupby("region").max() will not do it — that aggregates every column independently, so you can end up with one region's highest sales sitting next to a different product's name. A row that never existed.
groupby(...)["sales"].idxmax() instead returns one label per group . Feed those labels to .loc and you get real, intact rows:
4 Edge Cases: Ties, NaN, Empty & axis=1
- Ties: only the first matching label comes back. If you need every winner, compare instead: df[df["sales"] == df["sales"].max()] .
- NaN: ignored by default ( skipna=True ). Set skipna=False and any NaN present makes the result NaN.
- Empty or all-NaN: raises ValueError: attempt to get argmax of an empty sequence . Check s.notna().any() first.
- axis=1: scans across columns and returns the column name holding each row's maximum — handy for "which month was this shop's best?".
5 🎯 Your Turn
Given a table of city temperature readings, find the single hottest reading, the single coldest, and the hottest reading in each country — keeping every column of those rows intact.
❓ Frequently Asked Questions
Lesson complete — you can now name the winner, not just the number!
You know that idxmax returns a label, that .loc turns that label into a full row, and that groupby(...).idxmax() is the honest way to get the best record per group.
🚀 Up next: Ranking & Top-N — rank rows and pull the top few with rank and nlargest .
Practice quiz
What does df["sales"].idxmax() return?
- The largest sales value
- The index label of the largest value
- The row as a Series
- The column name
Answer: The index label of the largest value. idxmax returns the index LABEL where the maximum sits — not the value itself.
How do you get the whole row containing the largest value?
- df.max()
idxmax gives you the label; feed that label to .loc to pull back the entire row.
What is the difference between .max() and .idxmax()?
- They are identical
- max returns the value, idxmax returns where it is
- max is faster
- idxmax only works on integers
Answer: max returns the value, idxmax returns where it is. max answers 'what is the biggest number', idxmax answers 'which row holds it'.
If two rows tie for the maximum, what does idxmax return?
- Both labels
- The last one
- The first one it meets
- NaN
Answer: The first one it meets. Ties are broken by position — idxmax returns the first occurrence only.
By default, how does idxmax treat NaN values?
- Returns NaN
- Raises an error
- Skips them (skipna=True)
- Treats them as zero
Answer: Skips them (skipna=True). skipna defaults to True, so missing values are ignored when finding the maximum.
What happens if you call idxmax() on an empty Series?
- Returns None
- Returns 0
- Returns NaN
- Raises a ValueError
Answer: Raises a ValueError. There is no label to return, so pandas raises ValueError: attempt to get argmax of an empty sequence.
Which argument makes idxmax scan across columns instead of down rows?
- axis=1
- across=True
- rows=False
- orient='columns'
Answer: axis=1. axis=1 works row-wise, returning the column NAME holding each row's maximum.
How do you find the best-selling row within every region?
- df.groupby('region').max()
- region
- sales
Answer: region. groupby(...).idxmax() gives one label per group; .loc turns those labels back into full rows.
How does argmax differ from idxmax?
- They are the same method
- argmax returns a position, idxmax returns a label
- argmax works on strings only
- argmax is deprecated
Answer: argmax returns a position, idxmax returns a label. argmax gives the integer POSITION (use with .iloc); idxmax gives the index LABEL (use with .loc).
Why is df.loc[df['x'].idxmax()] better than sorting the whole frame?
- It is not, sorting is always better
- It reads more clearly and avoids sorting every row
- It handles NaN differently
- Sorting cannot find a maximum
Answer: It reads more clearly and avoids sorting every row. Sorting rearranges every row just to read the top one; idxmax goes straight to it and states your intent.
Continue this course
- Previous: Sorting and Ranking
- Next: Ranking & Top-N