Find the max of two or more columns with pandas
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In pandas, the usual way to find the maximum across two or more columns is to select those columns and call .max(axis=1). That gives you the row-wise maximum. There are also useful variations when you only have two columns, need the column name of the winner, or want special handling for missing values.
The Standard Row-Wise Maximum
Suppose you have a DataFrame like this:
Output:
The important part is axis=1, which tells pandas to compare across columns for each row.
Finding the Maximum of Exactly Two Columns
If you only have two columns and want an explicit pairwise comparison, NumPy can be handy:
This is fast and clear for two-column comparisons, but .max(axis=1) scales more naturally when the number of columns grows.
Getting the Column Name of the Maximum
Sometimes you need to know not only the maximum value but also which column produced it. Use .idxmax(axis=1) for that.
This is a very common pattern in reporting and feature engineering.
Handling Missing Values
By default, pandas skips NaN values when possible:
If a row has at least one real value, pandas returns the maximum of the available values. If all selected columns are missing in a row, the result is NaN.
This default is usually what you want, but it is worth knowing because missing-data behavior affects downstream analysis.
Dynamic Column Lists
In real code, the columns are often not hard-coded. You can build the list dynamically and still use the same pattern.
This is useful in pipelines where the number of compared columns changes over time.
Avoid apply Unless You Need Custom Logic
You can write:
but .max(axis=1) is usually better. It is clearer, more idiomatic, and typically faster because it uses vectorized pandas logic instead of row-wise Python callbacks.
Reach for apply only when the rule is more complex than a straightforward maximum.
Example with a Custom Rule
If your logic is "take the max, but ignore negative values," then apply or preprocessing may make sense.
That kind of rule is where apply becomes justified.
Common Pitfalls
One common mistake is forgetting axis=1. Without it, .max() computes the maximum down each column instead of across columns per row.
Another issue is mixing non-numeric columns into the selection accidentally. Pandas may still attempt the operation, but the results can become confusing or error-prone depending on the data types involved.
Developers also sometimes use apply(max, axis=1) for simple cases where .max(axis=1) is cleaner and faster.
Finally, if you need the name of the winning column, remember that .max(axis=1) gives the value, while .idxmax(axis=1) gives the column label. They solve related but different problems.
Summary
- Use
df[columns].max(axis=1)for the row-wise maximum across two or more columns. - Use
np.maximumwhen you only need a fast pairwise maximum of two columns. - Use
.idxmax(axis=1)when you need the column name of the maximum value. - '
NaNvalues are skipped by default when possible.' - Prefer vectorized pandas methods over
applyunless the rule requires custom row logic.

