Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
pandas Series and DataFrames  ›  Lesson

Groupby and Aggregation

Groupby & Aggregation 15 mingroupby splits rows by a key, applies a summary such as sum or mean to each group, and combines the answers into one row per group.

Groupby and Aggregation

The owner's favourite question is "how is each branch doing?" That is not one number but one number per branch. Filtering three times and summing three times would work, but groupby does the whole thing in one line, for three branches or three hundred.

The rule

Split by a key, apply a summary, combine into one row per group.

sales.groupby("branch")["copies"].sum()
# branch
# Chennai    10
# Delhi       9
# Pune        7

Read it in three moves:

  1. Split: groupby("branch") sorts the rows into piles, one per branch.
  2. Apply: ["copies"].sum() totals the copies inside each pile.
  3. Combine: the answers come back as a Series whose index is the branch names, sorted alphabetically.

Common summaries: sum, mean, count, min, max, median, and size, which counts rows per group:

sales.groupby("branch").size()      # Chennai 2, Delhi 3, Pune 3

For several summaries at once, use agg:

sales.groupby("branch").agg(
    total_copies=("copies", "sum"),
    avg_copies=("copies", "mean"),
    revenue=("revenue", "sum"),
)
branch total_copies avg_copies revenue
Chennai 10 5.00 1720
Delhi 9 3.00 3450
Pune 7 2.33 1790

Each name=("column", "summary") pair makes one output column, so the result has tidy names.

Group by two keys by passing a list: sales.groupby(["branch", "genre"])["copies"].sum() gives one row per branch-genre pair that actually occurs.

The shortcut

Turn the question into the pattern "[summary] of [column] per [key]". The key goes in groupby, the column in the brackets, the summary at the end. Any English question with "per", "each" or "by" is a groupby.

Revenue per genreStep 1 of 4
  1. Fill the pattern

    Summary: total. Column: revenue. Key: genre.

The trap is confusing count and size. size counts every row in the group; count counts only the non-missing values in a column. They differ as soon as your data has gaps.

Drills

Answer fast — trust the rule.

quick drill

What does sales.groupby("genre")["copies"].sum() give for fiction?

quick drill

What is the index of sales.groupby("branch")["price"].mean()?

quick drill

Which line answers "average copies per sale in each genre"?

quick drill

How many rows does sales.groupby(["branch", "genre"])["copies"].sum() have?

Remember

  • Split by a key, apply a summary, combine into one row per group.
  • Pattern: "[summary] of [column] per [key]".
  • size counts rows; count counts non-missing values.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainOne line per branch

Explain how you would produce a table with, for each branch, the number of sales, the total copies and the average revenue, and describe what groupby does in each step.