Summaries by Group in Pandas – GroupBy & Aggregation Best Practices 2026
Grouping data and calculating summary statistics by category, region, time period, or any other key is one of the most powerful and frequently used techniques in data manipulation. In 2026, combining groupby() with .agg() and method chaining is the standard, cleanest, and most efficient way to create grouped summaries.
TL;DR — Modern GroupBy Pattern
- Use
groupby()+.agg()for multiple statistics - Prefer named aggregation syntax for readable column names
- Combine with date components for time-based grouping
- Use method chaining for clean, readable code
1. Basic 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"])
# Simple groupby summary
summary = df.groupby("region").agg({
"amount": ["sum", "mean", "count"],
"customer_id": "nunique"
}).round(2)
print(summary)
2. Advanced Grouped Summaries by Multiple Keys (Recommended in 2026)
result = (
df
.groupby(["region", df["order_date"].dt.to_period("M")])
.agg(
total_sales=("amount", "sum"),
average_sale=("amount", "mean"),
order_count=("amount", "count"),
unique_customers=("customer_id", "nunique"),
total_quantity=("quantity", "sum")
)
.round(2)
.reset_index()
)
print(result)
3. Grouped Summaries with Date Components
monthly_summary = (
df
.groupby([
"region",
df["order_date"].dt.year.rename("year"),
df["order_date"].dt.month.rename("month")
])
.agg(
total_sales=("amount", "sum"),
avg_order_value=("amount", "mean"),
transaction_count=("amount", "count")
)
.round(2)
.reset_index()
)
4. Best Practices in 2026
- Use named aggregation syntax (
new_name=("column", "func")) for clean, meaningful column names - Combine
groupby()with date components using.dtaccessor - Always use method chaining to keep your code readable
- Round final results for professional-looking output
- Use
.reset_index()when you need a flat table for further analysis or export
The Split-Apply-Combine Idea
Every grouped summary follows the same three steps. pandas splits the rows into groups by the key you give, applies a function such as sum or mean to each group, and combines the results into a new table with one row per group. Once you see groupby() this way, it becomes easy to read any grouped expression: the part before .agg() describes the split, and the part inside describes what is calculated.
By default the group keys become the index. Add as_index=False or call reset_index() when you want them back as ordinary columns. Keys can be columns, a list of columns, a Series or a function applied to the index.
Worked Example: Share of Total per Group
A common follow-up to a grouped sum is each group's share of the total.
import pandas as pd
df = pd.DataFrame({
"category": ["Books", "Toys", "Books", "Games", "Toys"],
"amount": [40.0, 25.0, 60.0, 50.0, 25.0],
})
by_cat = df.groupby("category", as_index=False)["amount"].sum()
by_cat["share_pct"] = (by_cat["amount"] / by_cat["amount"].sum() * 100).round(1)
print(by_cat.sort_values("amount", ascending=False))
# category amount share_pct
# 0 Books 100.0 50.0
# 1 Games 50.0 25.0
# 2 Toys 50.0 25.0
Because as_index=False keeps the category as a column, the result is ready to plot or export.
Common Mistakes
- Forgetting missing keys: rows with NaN keys are dropped unless you pass
dropna=False - Grouping on unsorted categories and expecting order: sort the result explicitly
- Selecting columns after
agg(): select before aggregating to save work - Mixing up index and columns: use
as_index=Falsewhen you need flat output
Quick Summary
groupby()= split, apply, combine- Select columns before aggregating
- Use
as_index=Falsefor tidy, flat results
Conclusion
Creating summaries by group is a fundamental skill in data manipulation. In 2026, the combination of groupby(), named aggregation, and method chaining gives you maximum flexibility and readability. Whether you are summarizing sales by region, user behavior by month, or any other grouped analysis — mastering these patterns will make your reports insightful, clean, and professional.
Next steps:
- Take one of your datasets and create a grouped summary using named aggregation syntax