Multiple Grouped Summaries in Pandas – Advanced GroupBy Techniques 2026
When you need to calculate several different summary statistics across multiple groups and columns, Pandas offers powerful and elegant solutions. In 2026, using groupby() combined with named aggregation in .agg() is the cleanest, most readable, and most performant way to create complex multi-group summaries.
TL;DR — Recommended Pattern
- Use
groupby([col1, col2])with named aggregation - Apply different functions to different columns in one operation
- Use method chaining for clarity
- Combine with date components for time-based grouping
1. Basic Multiple Grouped Summaries
import pandas as pd
# Create a small demo file so this example runs as-is
# (in your project, sales_data.csv is your real export)
import numpy as np
rng = np.random.default_rng(42)
n = 60
pd.DataFrame({
"order_date": pd.date_range("2025-10-01", periods=n, freq="3D"),
"customer_id": rng.integers(101, 121, n),
"customer_name": rng.choice([" ana", "ben ", "chen", "dana"], n),
"product_id": rng.integers(1, 9, n),
"region": rng.choice(["North", "South", "East", "West"], n),
"category": rng.choice(["Electronics", "Books", "Home"], n),
"payment_method": rng.choice(["card", "cash", "wallet"], n),
"segment": rng.choice(["consumer", "business"], n),
"quantity": rng.integers(1, 6, n),
"amount": rng.uniform(50, 2500, n).round(2),
}).assign(
ship_date=lambda d: d["order_date"] + pd.Timedelta(days=2),
status=lambda d: np.where(d["amount"] > 2000, "priority", "standard"),
).to_csv("sales_data.csv", index=False)
df = pd.read_csv("sales_data.csv", parse_dates=["order_date"])
summary = (
df
.groupby(["region", "category"])
.agg(
total_sales=("amount", "sum"),
avg_sale=("amount", "mean"),
order_count=("amount", "count"),
unique_customers=("customer_id", "nunique"),
total_quantity=("quantity", "sum")
)
.round(2)
.reset_index()
)
print(summary)
2. Advanced Multi-Level Grouped Summaries with Dates
monthly_report = (
df
.groupby([
"region",
df["order_date"].dt.to_period("M").rename("month"),
"category"
])
.agg(
total_sales=("amount", "sum"),
average_order_value=("amount", "mean"),
transaction_count=("amount", "count"),
unique_customers=("customer_id", "nunique"),
max_sale=("amount", "max"),
min_sale=("amount", "min")
)
.round(2)
.reset_index()
)
print(monthly_report)
3. Using Custom Functions in Multiple Grouped Summaries
def cv(x):
"""Coefficient of variation"""
return x.std() / x.mean() if x.mean() != 0 else 0
report = (
df
.groupby(["region", "category"])
.agg(
total_revenue=("amount", "sum"),
avg_revenue=("amount", "mean"),
revenue_volatility=("amount", cv),
customer_count=("customer_id", "nunique"),
product_diversity=("product_id", "nunique")
)
.round(2)
)
4. Best Practices in 2026
- Use named aggregation syntax (
new_name=("column", "func")) for clear, meaningful column names - Group by multiple columns including date components using
.dt.to_period() - Always use method chaining to keep complex aggregations readable
- Round results and use
.reset_index()for clean output - Define small custom functions when you need special calculations
Working with Multi-Level Results
When you request several statistics for several columns, pandas returns MultiIndex columns such as ("amount", "sum"). They are powerful for exploring but awkward for exports and charts. You can either use named aggregation from the start or flatten the columns afterwards by joining the two levels with an underscore. Flat names also make later steps like merge() and query() simpler.
Grouped results can also be compared with the overall figure by using transform(), which returns a value for every original row. For example, df["amount"] / df.groupby("region")["amount"].transform("sum") gives each order's share of its region total.
Worked Example: Flattening Column Names
This example creates multi-level columns and converts them into simple names.
import pandas as pd
df = pd.DataFrame({
"region": ["East", "East", "West", "West"],
"amount": [10.0, 30.0, 20.0, 40.0],
"quantity": [1, 3, 2, 2],
})
res = df.groupby("region").agg({"amount": ["sum", "mean"], "quantity": ["sum"]})
res.columns = ["_".join(col) for col in res.columns]
print(res.reset_index())
# region amount_sum amount_mean quantity_sum
# 0 East 40.0 20.0 4
# 1 West 60.0 30.0 4
The flat names work with to_csv(), SQL exports and plotting libraries without further changes.
Common Mistakes
- Indexing MultiIndex columns by a single name:
res["sum"]fails; use tuples or flatten - Using
apply()for simple statistics:agg()is clearer and faster - Repeating
groupby()for each metric: compute them together - Forgetting
reset_index()before saving, which leaves the group keys hidden in the index of the exported file
Quick Summary
- Several statistics produce MultiIndex columns
- Flatten with
"_".joinor use named aggregation - Calculate every metric in one grouped call
Conclusion
Creating multiple grouped summaries is one of the most powerful capabilities in Pandas. In 2026, the combination of groupby() with named aggregation allows you to generate rich, insightful reports with very clean and maintainable code. Whether you are analyzing sales by region and month, user behavior by category, or any multi-dimensional data — this pattern will serve you extremely well.
Next steps:
- Take one of your current datasets and create a multi-column, multi-group summary using named aggregation