Filtering with query() & eval()

df.query() filters rows using a plain-English string expression — like "age > 30 and city == 'NYC'" — instead of stacking bracketed boolean masks.

Learn Filtering with query() & eval() in our free Pandas course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a…

Part of the free Pandas course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

Learn to write readable multi-condition filters, reference Python variables with @, compute new columns with eval(), and know when string expressions beat boolean masks.

df.query() takes a string and keeps the rows where it is true. Inside the string you write column names bare — no df["..."] — and you may use the friendly words and , or , and not instead of the bitwise & , | , ~ . A filter that needs three sets of brackets as a mask becomes one clean sentence.

Filters are rarely hard-coded — the threshold often lives in a variable. Inside a query string, prefix a Python variable with @ to use its value. df.query("age > @cutoff") reads cutoff from your code. Without the @ , query assumes you mean a column called cutoff and raises an error when it cannot find one.

Where query() selects rows, eval() calculates values. Hand it an arithmetic expression over your columns and it returns the result; use the "new = ..." form to attach it as a column. It keeps long formulas readable and, on big frames, can run faster by avoiding temporary intermediate arrays.

An unquoted string value is read as a variable name:

Use query and eval together on an orders table.

Lesson complete — your filters read like English!

You can filter with df.query() , combine clauses with and / or , inject variables with @ , and compute new columns with df.eval() .

🚀 Up next: Replacing Values — swap, blank out, and clamp values with replace, where, and mask.

Practice quiz

What does df.query() return?

  • The rows where the expression is true
  • A single boolean value
  • The column names only
  • A sorted copy of the frame

Answer: The rows where the expression is true. query() keeps the rows for which the string expression evaluates to True.

Inside a query string, how do you reference a Python variable named cutoff?

  • #cutoff
  • @cutoff
  • $cutoff
  • %cutoff

Answer: @cutoff. Prefix the variable with @, e.g. df.query('age > @cutoff').

Which method computes a new column from an expression?

  • df.filter()
  • df.select()
  • df.eval()
  • df.where()

Answer: df.eval(). df.eval('total = price * qty') evaluates the expression and can attach it as a column.

How must a string value be written inside a double-quoted query?

  • Left unquoted, like NYC
  • With backticks, like

Wrap text values in single quotes so they are not read as variable names: city == 'NYC'.

Which words can replace &, |, ~ inside a query expression?

  • and, or, not
  • AND, OR, NOT only
  • plus, minus, no
  • with, without, none

Answer: and, or, not. query() accepts the readable keywords and, or, and not.

What does df.query('city in @cities') do?

  • Adds a cities column
  • Keeps rows whose city is in the list cities
  • Sorts by city
  • Renames the city column

Answer: Keeps rows whose city is in the list cities. in with @list is the readable equivalent of .isin() on a boolean mask.

By default, df.eval('total = price * qty') returns what?

  • Nothing, it mutates in place silently
  • A plain Python list
  • A new DataFrame with the extra column
  • Only the total Series

Answer: A new DataFrame with the extra column. It returns a new DataFrame with the computed column, so assign it back.

What error appears for df.query('city == NYC')?

  • SyntaxError: invalid token
  • ValueError: bad expression
  • KeyError: NYC
  • name 'NYC' is not defined

Answer: name 'NYC' is not defined. Unquoted NYC is treated as a variable name; quote it as 'NYC'.

Why might query()/eval() run faster on large frames?

  • They can use the numexpr engine and avoid temporary arrays
  • They skip type checking entirely
  • They cache every result to disk
  • They run on the GPU automatically

Answer: They can use the numexpr engine and avoid temporary arrays. pandas can evaluate the expression with numexpr, avoiding intermediate arrays.

Given df with age column, what does df.query('age > 30')['name'] return?

  • The whole DataFrame
  • The name values for rows where age exceeds 30
  • A count of matching rows
  • The age column instead

Answer: The name values for rows where age exceeds 30. query() filters rows first, then ['name'] selects that column from the result.