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

>>> total quantity per product
import pandas as pd

df = pd.DataFrame({
    "product": ["Notebook", "Pen", "Notebook", "Pen"],
    "quantity": [4, 10, 2, 5]
})
print(df.groupby("product")["quantity"].sum())
Output
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.

Note: 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:

>>> multiple aggregates
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)
Output
          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

>>> two grouping keys
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())
Output
region  product
North   Notebook    4
        Pen        10
South   Notebook    3
        Pen         6
Name: quantity, dtype: int64

Passing 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.