Raw datasets are often too granular. To find the average sales per region or the total users per month, you need to group data. Pandas uses the 'Split-Apply-Combine' strategy to make these calculations efficient and easy to write.
1Split-Apply-Combine
This is the core philosophy of grouping. First, you split the data into groups based on a key (like Category). Then, you apply a function (like sum or mean) to each group. Finally, you combine the results into a new DataFrame.
2Pivot Tables: High-Level Views
When you need to cross-tabulate data across multiple dimensions (e.g., Sales by Region AND Product), pivot tables provide a powerful Excel-like interface to summarize information in a 2D matrix.
3Step-by-Step Breakdown
Raw datasets are often too granular. Pandas allows us to group rows sharing identical values and aggregate them to find insights.
The core concept is 'Split-Apply-Combine'. First, we split the data into groups using .groupby().
The result is a Series with the Department as the index and the aggregated mean Salary as values.
Checkpoint: What is the first phase of the Split-Apply-Combine methodology?
We can perform multiple aggregations at once using the .agg() method, passing a list of functions.
This returns a DataFrame where each aggregation function becomes a new column.
Checkpoint: Which method allows you to execute multiple different aggregation functions simultaneously?
For cross-tabulation, pivot_table provides an Excel-like interface to summarize data across multiple dimensions.
Ready to crunch the numbers? Register and login to save your progress and unlock the 'Group Guru' achievement!
Run a Real Group-By Aggregation. Finish grouping by Department and computing the average salary per group.
Level Up 🚀
Advanced cheat sheets, SEO tricks, and interview prep for this topic.
Browser Support
Fully supported.
Fully supported.
Fully supported.
Fully supported.
Accessibility (A11y)
1Present GroupBy Results as Real Tables
A grouped/aggregated result is inherently tabular data — render it as a genuine HTML <table> with <th> headers when displaying it on a page, rather than a styled <div> grid, so screen readers can announce row/column relationships instead of a flat, disconnected list of numbers.
<table>
<tr><th>Department</th><th>Avg Salary</th></tr>
<tr><td>Engineering</td><td>95000</td></tr>
</table>SEO Implications
- 1
Aggregated DataFrames Exist Only in Analysis Sessions
The output of a .groupby().agg() call lives in a notebook or script's memory, never as its own indexable URL — this page's SEO value comes entirely from its own explanation of the Split-Apply-Combine pattern, not from any specific aggregation result shown in the examples.
Best Practices
Use Named Aggregation for Readable Column Names
df.groupby('dept').agg(avg_salary=('salary', 'mean')) produces a clearly-named avg_salary column, versus the default df.groupby('dept')['salary'].agg(['mean']) which leaves you with an ambiguous 'mean' column name when multiple aggregations are combined.
Reset the Index After Grouping When You Need a Flat DataFrame
groupby() results use the grouping key as the new index, which is convenient for further analysis but can break code that expects the original column-based structure. Call .reset_index() when you need the group key back as a regular column, such as before merging with another DataFrame.
Frequent Bugs
Forgetting that a groupby() call alone returns a lazy GroupBy object, not a DataFrame.
df.groupby('dept') by itself produces a DataFrameGroupBy object, not a result you can inspect or print meaningfully — you must chain an aggregation like .mean() or .agg() to actually compute and materialize a result. Printing the bare GroupBy object shows an unhelpful memory address, not your data.
Real-World Examples
A Sales Dashboard's Regional Summary Query
A sales dashboard backend runs df.groupby(['region', 'quarter']).agg(total_sales=('sales', 'sum'), avg_deal_size=('sales', 'mean')).reset_index() to power a table showing every region-quarter combination's total and average deal size in one query, rather than looping through regions and quarters manually in application code.
summary = df.groupby(['region', 'quarter']).agg(
total_sales=('sales', 'sum'),
avg_deal_size=('sales', 'mean')
).reset_index()