HOWTO · Pandas
How to Get Index of All Rows Whose Particular Column Satisfies Given Condition in Pandas
We can get indices of all rows whose particular column satisfies given condition in Pandas using simple indexing operation, np.where() function, and query() method.
On this page
To retrieve rows where a Pandas column meets a predicate, use Boolean indexing and read the filtered DataFrame’s .index. This returns index labels, which identify rows and may not be their numeric positions. np.where() can instead return positions in the condition array, while DataFrame.query() filters rows using an expression and also preserves their index labels. Choose the result that the next step needs.
Use Boolean indexing to get matching row indexes
A comparison such as df["Sales"] >= 300 creates a Boolean Series aligned with the DataFrame’s rows. Use that Series inside df[...] to keep matching rows, then access .index. Calling .tolist() converts the index to a regular Python list when that is more convenient to pass to another function or display.
Run this example:
import pandas as pd
df = pd.DataFrame(
{"Sales": [200, 300, 400, 200, 300, 300]},
index=[10, 11, 12, 13, 14, 15],
)
mask = df["Sales"] >= 300
matching_rows = df[mask]
print(mask.tolist())
print(matching_rows)
print(matching_rows.index.tolist())
The mask marks each row whose Sales value is at least 300. matching_rows.index contains the labels for those retained rows; converting it with .tolist() gives a list of labels. In this example the labels are deliberately different from the rows’ positions, so the distinction is visible.
Understand index labels and row positions
An index label is the identifier stored in a DataFrame’s index. A row position is its zero-based offset in the current row order. For a default RangeIndex, labels often look like positions, but that is only a convenient coincidence. A filtered DataFrame keeps the original labels rather than renumbering its rows. Use .index when you need those identifiers; use a positional result when an API expects offsets into the current array or row order.
Use np.where() to get matching row positions
np.where() is a NumPy function, not a Pandas method. Given a one-dimensional Boolean condition, it returns a tuple containing an array of positions where the condition is true. Select the first tuple element with [0] to get the flat array of row positions. These are positions in the Boolean array, not the DataFrame’s index labels, so they can differ when the DataFrame has a custom index.
import numpy as np
import pandas as pd
df = pd.DataFrame({"Sales": [200, 300, 400, 200, 300, 300]}, index=[10, 11, 12, 13, 14, 15])
mask = df["Sales"] >= 300
positions = np.where(mask.to_numpy())[0]
print(positions.tolist())
Use np.where(mask.to_numpy())[0] when you specifically need matching positions. Wrapping the full call in list(...) produces a list containing the tuple’s array; it is not the same flat list of positions. For index labels, prefer the filtered DataFrame’s .index instead.
Use DataFrame.query() to filter rows and get their index
DataFrame.query() evaluates a string expression against column names and returns the matching rows as a DataFrame. Read .index from that result to get the original labels, and use .tolist() if a list is required. Keep the expression’s column name and comparison consistent with the DataFrame; here, the predicate selects Sales values equal to 300.
import pandas as pd
df = pd.DataFrame({"Sales": [200, 300, 400, 200, 300, 300]}, index=[10, 11, 12, 13, 14, 15])
labels = df.query("Sales == 300").index.tolist()
print(labels)
For labels from an expression-based filter, use df.query("Sales == 300").index. For positions from a Boolean condition, use np.where(condition)[0]. Boolean indexing is the direct choice when you want both the matching rows and their labels. The three forms answer related questions, but only the first and third return the DataFrame’s index labels.