Q&A library Python

How do I check whether every column in a row meets a condition?

Python Intermediate allanyaxis

Short answer

Apply the condition to the whole frame and reduce with all(axis=1) for a per-row answer, or all(axis=0) for a per-column one. The axis argument decides which direction is collapsed.

The short version

Build a boolean frame with your condition, then reduce it with .all(axis=1) to get one answer per row, or .all(axis=0) for one per column. The axis you name is the one that disappears. any works the same way for "at least one".

Per row and per column

import pandas as pd

df = pd.DataFrame({"a": [1, 5], "b": [2, 6]})

positive = df > 3

positive.all(axis=1).tolist()   # [False, True] , one answer per row
positive.all(axis=0).tolist()   # [False, False] , one answer per column

Row 1 has both values above 3, so it is True. Row 0 does not. With axis=0, neither column is entirely above 3.

Remembering the axis

The rule that works everywhere in pandas and NumPy: the axis you name is collapsed. axis=1 collapses the columns, leaving one value per row. axis=0 collapses the rows, leaving one value per column.

If you get a result with the wrong length, you have almost certainly used the other axis.

Filtering on a whole-row condition

The natural use is keeping rows where every column passes a check.

complete = df[df.notna().all(axis=1)]     # rows with no missing values anywhere

This is exactly what dropna() does, but writing it explicitly lets you vary the rule, for example requiring only certain columns to be present.

key_columns = ["city", "amount"]
df[df[key_columns].notna().all(axis=1)]

Checking a subset of columns

Select the columns first, then reduce, which is clearer than trying to express the restriction inside the condition.

numeric = df.select_dtypes("number")
df[(numeric > 0).all(axis=1)]      # rows where every numeric column is positive

any for the opposite question

df[(df < 0).any(axis=1)]    # rows with at least one negative value anywhere

This is a fast way to find problem rows across a wide frame without naming each column.

Reducing to a single answer

Chaining two reductions collapses the whole frame to one boolean, which is how you write a validation check.

if (df < 0).any().any():
    raise ValueError("negative values found somewhere in the data")

The first any() gives one answer per column, the second collapses those to one overall. Forgetting the second call leaves you with a Series where you expected a boolean, and using it in an if raises the ambiguous-truth-value error.

Counting instead of testing

Summing the boolean frame tells you how many cells, rows or columns are affected, which is often more useful than a bare True or False.

(df < 0).sum()             # count of negatives per column
(df < 0).any(axis=1).sum() # how many rows contain any negative

These two numbers together tell you both the scale of a data problem and whether it is concentrated in a few rows or spread everywhere, which usually points straight at the cause.

Need this solved on your own data?

The library is free and always will be. When the problem is bigger than an answer, we take on the work.

Start a project