Chapter 5 · Part 2
Grouping & aggregating
Here's the move that turns a table into an answer. "What's the average rating per genre?"
"How many films per decade?" Every question shaped like "something, per category" is a
groupby — the single most powerful idea in pandas. (We're back to the clean movies table.)
Split, apply, combine
groupby works in three steps, and it's worth picturing them: split the rows into groups by
some column, apply a summary to each group, then combine the results into a new table.
Start simple — count how many films are in each genre:
movies["genre"].value_counts()genre
Sci-Fi 4
Drama 2
Thriller 1
Animation 1
Name: count, dtype: int64value_counts() is the quick one-column shortcut. The general tool is groupby. Group by genre,
pick a column, apply a summary — here, the mean rating of each genre:
movies.groupby("genre")["rating"].mean()genre
Animation 8.400
Drama 8.250
Sci-Fi 8.525
Thriller 8.500
Name: rating, dtype: float64Read it left to right: groupby("genre") splits the rows, ["rating"] picks the column,
.mean() is the summary applied to each group. The genre becomes the new index.
Many summaries at once with .agg
Usually you want several numbers per group. .agg names each output column and pairs it with
(source_column, function):
movies.groupby("genre").agg(
count=("title", "size"),
avg_rating=("rating", "mean"),
total_votes=("votes", "sum"),
)count avg_rating total_votes
genre
Animation 1 8.400 520
Drama 2 8.250 1460
Sci-Fi 4 8.525 6750
Thriller 1 8.500 780That's a pivot table, in four lines. size counts rows in the group; mean, sum, min,
max, std all work too.
Sorting the result
Aggregations come out sorted by the group label. To rank by a value instead, chain
sort_values:
movies.sort_values("votes", ascending=False)[["title", "votes"]].head(4)title votes
0 Inception 2400
1 The Matrix 1900
2 Interstellar 1800
4 Whiplash 900You now know every core move. Time to chain them into a real analysis.