Pandasdrill

Selecting and filtering Updated November 2026

Filter rows

Filter a DataFrame by indexing it with a boolean Series: df[df["amount"] > 100]. Combine conditions with & (and), | (or) and ~ (not), wrapping each condition in parentheses, because Python's and/or do not work on Series.

Syntax

df[(cond1) & (cond2)]   |   df.loc[mask, cols]

Examples

import pandas as pd

df = pd.DataFrame({"name": ["Ana", "Ben", "Cara", "Dan"],
                   "dept": ["Sales", "IT", "Sales", "HR"],
                   "salary": [50000, 62000, 58000, 45000]})
df[df["salary"] > 55000]

Result: name dept salary 1 Ben IT 62000 2 Cara Sales 58000

df[(df["dept"] == "Sales") & (df["salary"] >= 55000)]

Result: name dept salary 2 Cara Sales 58000

Parentheses are required: & binds tighter than == in Python.

df[~df["dept"].isin(["IT", "HR"])]

Result: name dept salary 0 Ana Sales 50000 2 Cara Sales 58000

Common mistakes

  • ValueError: The truth value of a Series is ambiguous: you used and/or/not between conditions; replace them with &, | and ~ and add parentheses.
  • Filtering text with == misses rows because of case or whitespace: normalize first with df["col"].str.strip().str.lower().
  • Comparing with None or NaN with == never matches; use df["col"].isna() or notna().

Practice Filter rows

These drills check your answer on live data, free, no account needed.

  • Filter with a boolean maskReturn every employee in `emp` whose salary is strictly greater than 80,000. Keep all columns and the original row labels.
  • Ranges with betweenReturn the employees with between 3 and 6 years of service, including both 3 and 6.

Questions

How do I filter rows where a column is in a list?

Use df[df["col"].isin(["a", "b"])]. Negate with ~ to exclude the list.

How do I filter by multiple conditions?

Wrap each condition in parentheses and join them with & for and, | for or: df[(df.a > 1) & (df.b == "x")]. For readability, df.query("a > 1 and b == 'x'") does the same.

How do I filter rows that contain a substring?

df[df["col"].str.contains("text", na=False)]. Add case=False for case-insensitive matching.

Related

  • DataFrame.queryHow df.query works in pandas: conditions as a string with and, or, not, in, variables with @, column names with spaces, and when to use boolean masks instead.
  • isinHow to use isin in pandas to keep rows whose value is in a list, set or Series, exclude with ~, check several columns at once and avoid the type mismatch.
  • str.containsHow to use str.contains in pandas to find rows containing text: case-insensitive matching, several keywords with regex, literal characters, and the NaN error.
  • loc vs ilocThe difference between loc and iloc in pandas: loc selects by index label and column name, iloc by integer position. Slices, lists and boolean masks.

Previous: loc vs ilocNext: DataFrame.query