Skip to content
Python for Data Science
Python for Data 8 min read

Filtering, Sorting & Grouping

Ask real questions of your data — boolean masks, combined conditions, isin and between, loc vs iloc, sort_values, groupby aggregation, and pivot tables.

Download notebook Open Google ColabIn Colab: File → Upload notebook → pick the downloaded file.

A DataFrame you can only look at is a spreadsheet. A DataFrame you can query is a superpower. This lesson covers the operations that answer real questions: "which orders were over $50?", "what's the average rating per genre?", "who are our top five customers?" — all without a single loop.

We'll use one small cereal-style dataset throughout, so each cell is self-contained.

Boolean masks: filtering rows

The pattern is the one you met with NumPy: build a Series of True/False, then use it to index the DataFrame:

Python — runs in your browser

Read df[df["rating"] > 50] inside-out: the inner expression makes a boolean mask, the outer brackets keep only the True rows.

Combining conditions: the parentheses gotcha

Multiple conditions use & (and), | (or), and ~ (not) — not Python's and/or/not. And each condition must be wrapped in parentheses, because & binds tighter than >:

Python — runs in your browser

The classic error

df[df["sugars"] < 5 & df["rating"] > 40] — without parentheses — raises a confusing ValueError about "truth value of a Series is ambiguous", because Python evaluates 5 & df["rating"] first. When you see that error, check your parentheses (and that you used &/|, not and/or).

isin, between, and string filters

Three shortcuts save you from long chains of |:

Python — runs in your browser

The .str accessor exposes most Python string methods (contains, startswith, lower, split, …) applied to every value at once — vectorized, like everything else.

loc vs iloc

Both select rows and columns, but by different coordinates:

  • .loc[rows, cols] — by label (index values, column names); slices are inclusive
  • .iloc[rows, cols] — by integer position; slices exclude the end, like Python lists
Python — runs in your browser

That last pattern — df.loc[mask, column] — is also the safe way to modify a filtered subset (plain chained indexing like df[mask][col] = ... triggers the infamous SettingWithCopyWarning).

Sorting

sort_values orders rows by one or more columns:

Python — runs in your browser

groupby: split, apply, combine

groupby is the single most important pandas operation. It splits the table into groups, applies an aggregation to each, and combines the results into a new table:

Python — runs in your browser

The named-aggregation form — new_name=("column", "function") — keeps the output tidy and self-documenting.

pivot_table: groupby in two dimensions

When you want groups along both axes (rows and columns), reach for pivot_table:

Python — runs in your browser

Each cell is the mean rating for one (manufacturer, type) combination — the same result as groupby(["mfr", "type"]), just reshaped into a grid that's much easier to scan (and to feed into a heatmap, as you'll see in the seaborn lesson).

Check your understanding

5 questions · free
  1. Q1.Why does df[df.sugars < 5 & df.rating > 40] raise an error?

  2. Q2.Which expression keeps rows where mfr is either "K" or "N"?

  3. Q3.What's the key difference between .loc and .iloc slicing?

  4. Q4.df.groupby("mfr")["rating"].mean() implements which pattern?

  5. Q5.When is pivot_table more convenient than a plain groupby?

Exercise: Query an orders table

Build an orders DataFrame with columns city (3 cities, 10 rows), payment ("card", "cash", "e-wallet"), and amount. Then answer: (1) which orders exceed 100? (2) which are card orders over 100 (two conditions)? (3) for each city, how many orders, total, and average amount (one groupby().agg())? (4) build a pivot_table of total amount by city × payment method.

You can now slice, dice, and summarize tables — next we make the numbers visible with Matplotlib.