Summaries on Multiple Columns in Pandas – Advanced Aggregations 2026
When performing data manipulation, you often need different summary statistics for different columns at the same time. In 2026, Pandas makes this elegant and efficient using the .agg() method with multiple columns and custom functions.
TL;DR — Best Ways to Summarize Multiple Columns
- Use dictionary syntax in
.agg()for full control - Named aggregation syntax for clean column names
- Combine with
groupby()for segmented analysis - Use lambda or custom functions when needed
1. Basic Multi-Column Aggregation
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.agg({
"amount": ["sum", "mean", "median", "min", "max", "std"],
"quantity": ["sum", "mean", "max"],
"customer_id": "nunique",
"region": "nunique"
}).round(2)
print(summary)
2. Grouped Summaries on Multiple Columns (Most Common Pattern)
result = (
df
.groupby(["region", df["order_date"].dt.to_period("M")])
.agg({
"amount": ["sum", "mean", "count"],
"quantity": ["sum", "mean"],
"customer_id": "nunique",
"product_id": "nunique"
})
.round(2)
)
# Flatten multi-level columns
result.columns = ["total_sales", "avg_sale", "order_count",
"total_quantity", "avg_quantity", "unique_customers", "unique_products"]
print(result)
3. Named Aggregation (Cleanest & Recommended in 2026)
monthly_summary = (
df
.groupby(["region", df["order_date"].dt.to_period("M")])
.agg(
total_sales=("amount", "sum"),
avg_sale=("amount", "mean"),
order_count=("amount", "count"),
total_qty=("quantity", "sum"),
unique_customers=("customer_id", "nunique")
)
.round(2)
.reset_index()
)
print(monthly_summary)
4. Using Custom Functions on Multiple Columns
def range_func(x):
return x.max() - x.min()
summary = (
df
.groupby("region")
.agg(
sales_range=("amount", range_func),
qty_range=("quantity", range_func),
amount_per_order=("amount", "mean")
)
)
print(summary)
Best Practices in 2026
- Use named aggregation syntax for readable column names
- Always round final results for clean output
- Combine with
.reset_index()when you need flat DataFrames - Define small helper functions for complex calculations
- Use method chaining for better readability
Why Summarise Several Columns Together
Real questions rarely involve one column. A sales manager wants revenue, units and order count per region at the same time, and calculating them in separate steps means separate group operations and a manual merge. pandas can compute every column in one pass, which is faster and guarantees that all numbers describe exactly the same groups.
The key decision is the output shape. A dictionary of lists gives MultiIndex columns, which are handy for exploring, while named aggregation gives one flat column per metric, which is better for reports and exports.
Worked Example: Ratios Built from Several Sums
Some metrics, like average price per unit, must be calculated from totals after grouping, not averaged row by row.
import pandas as pd
df = pd.DataFrame({
"region": ["North", "North", "South", "South"],
"amount": [100.0, 300.0, 50.0, 150.0],
"quantity": [1, 5, 1, 1],
})
summary = df.groupby("region").agg(revenue=("amount", "sum"), units=("quantity", "sum"))
summary["price_per_unit"] = summary["revenue"] / summary["units"]
print(summary)
# revenue units price_per_unit
# region
# North 400.0 6 66.666667
# South 200.0 2 100.000000
Averaging the row-level prices for North would give 80.0, which overweights the small order. Dividing the totals gives the true weighted value.
Common Mistakes
- Averaging ratios: compute ratios from summed columns after the aggregation
- Including ID columns: summing customer IDs produces meaningless numbers; select the columns you need
- Mixing text columns into
sum: string columns get concatenated or raise errors - Losing track of MultiIndex columns: flatten them or use named aggregation
Quick Summary
- Aggregate many columns in one
agg()call - Build ratios from totals, not from row averages
- Named aggregation keeps the result flat and readable
Conclusion
Summarizing multiple columns efficiently is a core skill in Pandas data manipulation. In 2026, the combination of .agg() with named aggregation and proper grouping gives you maximum flexibility and clean, professional-looking results. Master these patterns and your summary reports will become much more insightful and maintainable.
Next steps:
- Take one of your current groupby operations and rewrite it using named aggregation syntax