Filtering, Sorting and Grouping Data
With clean data loaded, you can start answering questions. Filtering, sorting and grouping are the tools you will use most.
The Data
We use the bakery sales.csv file from the Loading Data chapter, and add a total column:
Example
import pandas as pd
df = pd.read_csv("sales.csv")
df["total"] = df["quantity"] * df["price"]Filtering Rows
Put a condition inside square brackets. Only rows where it is True are kept:
Example
print(df[df["branch"] == "Saddar"])date branch item quantity price total 0 2026-10-01 Saddar Cake 3 1200 3600 3 2026-10-02 Saddar Biscuits 8 250 2000 6 2026-10-04 Saddar Bread 6 150 900
Several conditions
Use & for "and", | for "or", and put each condition in brackets:
Example
print(df[(df["item"] == "Cake") & (df["quantity"] >= 3)])date branch item quantity price total 0 2026-10-01 Saddar Cake 3 1200 3600 4 2026-10-03 Orangi Cake 4 1200 4800
In pandas you must use & and |, not the Python words and and or, and every condition needs its own brackets.
Other ways to filter
| Code | Keeps rows where |
|---|---|
df[df["branch"].isin(["Orangi", "Gulshan"])] | Branch is one of the list |
df[df["item"].str.contains("Bis")] | Item contains the text "Bis" |
df[df["total"].between(1000, 3000)] | Total is from 1000 to 3000 |
df.query("total > 1500") | The condition written as a string is true |
Sorting
sort_values sorts by one or more columns. Here are the three biggest sales:
Example
print(df.sort_values("total", ascending=False).head(3))date branch item quantity price total 4 2026-10-03 Orangi Cake 4 1200 4800 0 2026-10-01 Saddar Cake 3 1200 3600 2 2026-10-02 Gulshan Cake 2 1200 2400
To sort by several columns: df.sort_values(["branch", "total"], ascending=[True, False]).
Grouping with groupby
groupby splits the data into groups, calculates something for each group, and combines the results. Which branch earned the most?
Example
by_branch = df.groupby("branch")["total"].sum()
print(by_branch.sort_values(ascending=False))branch Orangi 7550 Saddar 6500 Gulshan 4200 Name: total, dtype: int64
Orangi is the best branch. You can read the code as "group by branch, take the total column, and sum it".
Several calculations at once
agg runs more than one function per group:
Example
print(df.groupby("item")["quantity"].agg(["sum", "mean", "count"]))sum mean count item Biscuits 13 6.500000 2 Bread 28 9.333333 3 Cake 9 3.000000 3
Bread sells the most pieces, but earlier we saw that cakes bring the most money. Both facts matter for planning.
Common functions for agg and groupby:
| Function | Result per group |
|---|---|
sum | Total |
mean | Average |
median | Middle value |
count | Number of rows |
min / max | Smallest / largest |
nunique | Number of different values |
Pivot Tables
A pivot table puts one category in the rows and another in the columns, like an Excel PivotTable:
Example
table = pd.pivot_table(df, values="total", index="branch",
columns="item", aggfunc="sum", fill_value=0)
print(table)item Biscuits Bread Cake branch Gulshan 0 1800 2400 Orangi 1250 1500 4800 Saddar 2000 900 3600
fill_value=0 shows 0 where a branch sold none of an item, instead of NaN. Gulshan has not sold any biscuits yet.
Saving Your Results
Save a result to share with others:
Example
table.to_csv("branch_item_sales.csv")
table.to_excel("branch_item_sales.xlsx")Exercise
Exercise
Which code gives the average price for each item?
