How do I find where the smallest value is in pandas?
Short answer
idxmin gives the index label of the smallest value, while argmin gives its integer position. Use idxmin with loc to fetch the whole row, and be aware both silently pick the first of any ties.
The short version
idxmin() returns the index label of the row holding the smallest value, and argmin() returns its integer position. Pass idxmin() to .loc to fetch the whole row. Both silently return the first of any tied values.
Label versus position
import pandas as pd
s = pd.Series([3, 1, 2])
s.idxmin() # 1 , the index label
s.argmin() # 1 , the position
Here they agree, because the index is a default 0, 1, 2. They diverge as soon as the index is anything else.
s = pd.Series([3, 1, 2], index=["a", "b", "c"])
s.idxmin() # 'b' , the label
s.argmin() # 1 , the position
This is the same label-versus-position distinction as loc and iloc, and the same rule applies: use the label form unless position is genuinely what you mean.
Getting the whole row
df.loc[df["amount"].idxmin()] # the full row with the smallest amount
min() alone would give only the value, losing the context of which row it came from, which is usually the thing you actually wanted to know.
Per group
df.loc[df.groupby("city")["amount"].idxmin()]
This returns the lowest row within each city, complete with every column. It is the cleanest way to answer "the worst performer in each group".
The ties trap
If several rows share the minimum, idxmin returns the first one it meets, silently. If ties matter (a joint lowest score, a tied earliest date), that arbitrary choice is a real error. Filter on the value instead, which keeps every tied row.
df[df["amount"] == df["amount"].min()]
The all-NaN error
idxmin skips missing values, but if the column is entirely NaN it raises rather than returning anything. On a column that might be empty after filtering, guard against it.
if df["amount"].notna().any():
lowest = df.loc[df["amount"].idxmin()]
The duplicate-index trap
If the index has duplicate labels, df.loc[idxmin()] may return several rows rather than one, because the label matches more than one row. This is the same problem as any label lookup on a non-unique index. Reset the index first if the labels are not unique.
The maximum equivalents
Everything above mirrors exactly: idxmax, argmax, and nlargest for the top few. And as with the minimum, nsmallest(n) is more direct than sorting the whole frame and slicing, when you want the lowest few rather than just the lowest one.