By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.
A Hyper-Practical, Zero-Fluff Study Guide
You’re handed a 10GB CSV of e-commerce transactions. Your boss asks: - "How much revenue did we make per product category in Q3?" - "Which customer segment has the highest average order value?" - "Is there a correlation between discount rates and return rates?"
If you try to answer these with for loops or manual filtering, you’ll waste hours (or crash your notebook). Groupby, pivot tables, and cross-tabulations are your power tools—they let you slice, aggregate, and reshape data in seconds, not days.
for
Why this matters in production:- Speed: A well-written groupby can process millions of rows in milliseconds.- Clarity: Pivot tables turn raw data into human-readable summaries for stakeholders.- Debugging: Cross-tabulations help you spot anomalies (e.g., "Why does Region X have 10x more returns?").- Feature Engineering: Aggregated metrics (e.g., "avg purchase per customer") are gold for ML models.
groupby
Real-world scenario:You’re building a customer segmentation model. Raw transaction data is useless—you need aggregated features (e.g., "total spend in last 90 days," "avg items per order"). groupby and pivot tables are how you get there.
groupby()
df.groupby('region').sum().sort_values('revenue', ascending=False)
sum()
mean()
count()
max()
min()
agg()
python df.groupby('category').agg( avg_price=('price', 'mean'), total_sales=('quantity', 'sum') )
pivot_table()
margins=True
crosstab()
df.groupby(['region', 'product'])
unstack()
transform()
apply()
df.groupby('user_id')['value'].transform('mean')
filter()
df.groupby('user_id').filter(lambda x: len(x) > 5)
as_index
as_index=True
as_index=False
Prerequisites:- Python 3.8+ with pandas installed (pip install pandas).- A CSV file (sales_data.csv) with columns: order_id, customer_id, product, category, price, quantity, order_date, region.
pandas
pip install pandas
sales_data.csv
order_id
customer_id
product
category
price
quantity
order_date
region
import pandas as pd df = pd.read_csv("sales_data.csv") print(df.head()) print(df.info())
# Calculate total revenue per category revenue_by_category = df.groupby('category')['price'].sum().sort_values(ascending=False) print(revenue_by_category)
Output:
category Electronics 500000 Clothing 300000 Home 200000 Name: price, dtype: int64
region_stats = df.groupby('region').agg( total_revenue=('price', 'sum'), avg_order_value=('price', 'mean'), total_orders=('order_id', 'nunique') ).sort_values('total_revenue', ascending=False) print(region_stats)
total_revenue avg_order_value total_orders region West 400000 120.5 3320 East 350000 110.2 3178 South 250000 95.8 2610
pivot = pd.pivot_table( df, values='price', index='category', columns='region', aggfunc='sum', margins=True, # Adds "All" row/column fill_value=0 # Replaces NaN with 0 ) print(pivot)
region East South West All category Clothing 120000 80000 100000 300000 Electronics 150000 50000 300000 500000 Home 80000 120000 0 200000 All 350000 250000 400000 1000000
# Assume we have a 'returned' column (1=returned, 0=not returned) returns_crosstab = pd.crosstab( index=df['product'], columns=df['region'], values=df['returned'], aggfunc='sum', margins=True ) print(returns_crosstab)
region East South West All product Laptop 12 5 8 25 Shirt 3 2 1 6 Chair 1 4 0 5 All 16 11 9 36
# Calculate RFM (Recency, Frequency, Monetary) metrics from datetime import datetime df['order_date'] = pd.to_datetime(df['order_date']) today = datetime(2023, 12, 31) rfm = df.groupby('customer_id').agg( recency=('order_date', lambda x: (today - x.max()).days), frequency=('order_id', 'nunique'), monetary=('price', 'sum') ) print(rfm.head())
recency frequency monetary customer_id 1001 15 3 450.0 1002 45 1 120.0 1003 3 5 1200.0
sum
mean
df[df['region'] == 'West'].groupby(...)
agg(avg_price=('price', 'mean'))
agg({'price': 'mean'})
reset_index()
# Revenue by category and region (2023)
df['column'].unique()
groupby().size()
df.groupby('region').size()
df['price'] = pd.to_numeric(df['price'], downcast='float')
dtype='category'
df['region'] = df['region'].astype('category')
DataFrameGroupBy
.sum()
.mean()
fill_value=0
margins=False
df.groupby('category')['price'].mean()
❌ df.pivot_table(values='price', index='category', aggfunc='mean') (overkill for simple aggregations)
df.pivot_table(values='price', index='category', aggfunc='mean')
"How do you create a pivot table showing revenue by region and product, with row totals?"
✅ pd.pivot_table(df, values='revenue', index='region', columns='product', aggfunc='sum', margins=True)
pd.pivot_table(df, values='revenue', index='region', columns='product', aggfunc='sum', margins=True)
"What’s the difference between transform() and apply()?"
Challenge:You have a DataFrame df with columns user_id, purchase_amount, and loyalty_tier (values: "Bronze", "Silver", "Gold"). Write a one-liner to calculate the average purchase amount per loyalty tier, sorted from highest to lowest.
df
user_id
purchase_amount
loyalty_tier
Solution:
df.groupby('loyalty_tier')['purchase_amount'].mean().sort_values(ascending=False)
Why it works:- groupby('loyalty_tier') splits data by tier.- ['purchase_amount'].mean() calculates the average per tier.- sort_values(ascending=False) orders results from highest to lowest.
groupby('loyalty_tier')
['purchase_amount'].mean()
sort_values(ascending=False)
df.groupby('column')['value'].sum()
df.groupby(['col1', 'col2']).sum()
df.groupby('col').agg(avg=('val', 'mean'))
pd.pivot_table(df, values='val', index='row', columns='col', aggfunc='sum')
pd.crosstab(df['col1'], df['col2'])
df.groupby('col').filter(lambda x: len(x) > 5)
df.groupby('col')['val'].transform('mean')
df.groupby('col').apply(lambda x: x['val'].max() - x['val'].min())
df.groupby('col').sum()
fill_value
pivot_table(..., fill_value=0)
Join 4M+ learners. Unlock unlimited quizzes, wrong-answer tracking, flashcards + reminders, study guides, and 1-on-1 challenges.