Grouping & Aggregating
groupby is pandas' answer to "give me the total sales per region" — split the data into groups by a column's values, then apply an aggregate function to each group separately.
A basic groupby
import pandas as pd
df = pd.DataFrame({
"product": ["Notebook", "Pen", "Notebook", "Pen"],
"quantity": [4, 10, 2, 5]
})
print(df.groupby("product")["quantity"].sum())
product Notebook 6 Pen 15 Name: quantity, dtype: int64
Rows are split into groups by matching "product" value, then .sum() is computed within each group. Any aggregate works the same way — .mean(), .count(), .max(), and so on.
df.groupby("product") on its own doesn't print a table — it returns a lazy DataFrameGroupBy object that hasn't computed anything yet. Nothing actually happens until you chain an aggregation like .sum() onto it.Aggregating multiple columns at once
.agg() lets you apply different functions to different columns in one call:
df = pd.DataFrame({
"product": ["Notebook", "Pen", "Notebook", "Pen"],
"quantity": [4, 10, 2, 5],
"price": [3.5, 1.2, 3.5, 1.2]
})
summary = df.groupby("product").agg(
total_quantity=("quantity", "sum"),
avg_price=("price", "mean")
)
print(summary)
total_quantity avg_price product Notebook 6 3.5 Pen 15 1.2
This "named aggregation" form (total_quantity=("quantity", "sum")) also lets you name the resulting columns exactly what you want, instead of pandas picking a default name.
Grouping by multiple columns
df = pd.DataFrame({
"region": ["North", "North", "South", "South"],
"product": ["Pen", "Notebook", "Pen", "Notebook"],
"quantity": [10, 4, 6, 3]
})
print(df.groupby(["region", "product"])["quantity"].sum())
region product
North Notebook 4
Pen 10
South Notebook 3
Pen 6
Name: quantity, dtype: int64Passing a list of column names groups by every unique combination of those columns' values — the result has a two-level index, one level per grouping column.