Lesson 57 · Python for Retail E-commerce Analytics
Customer Segmentation Case Study: Python Training for Retail E-commerce Analytics
In this lesson, we will explore how to segment customers based on real retail transaction datasets. Segmenting customers helps retail businesses identify…
- CoursePython for Retail E-commerce Analytics
- Lesson57 of 43
- Video19 min
- FormatJupyter notebook · 18 code cells
What you'll learn
Data
No separate download needed — the notebook creates or downloads everything it uses.
📓 Full notebook
Download .ipynbCustomer Segmentation Case Study: Retail Analytics in Action#
- In this lesson, we will explore how to segment customers based on real retail transaction datasets.
- Segmenting customers helps retail businesses identify high-value shoppers, loyal buyers, and target groups for promotions.
- You will learn how to analyze transaction data, uncover purchase patterns, and extract actionable customer insights.
- The goal is to gain the skills to inform smarter marketing, product, and sales decisions.
import pandas as pd
import numpy as np
import warnings
warnings.filterwarnings('ignore')
Key Retail Analytics Concepts#
- Retail transaction datasets contain information about orders, customers, products, and sales.
- Each row usually represents one transaction or line-item, including fields like price, quantity, and customer ID.
- Revenue is calculated as price times quantity; it is important not to confuse it with the number of items sold.
- Beginners often make mistakes by mixing up transaction and customer levels, or grouping incorrectly.
# Load the Online Retail Transactions Dataset
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/00502/online_retail_II.xlsx'
df = pd.read_excel(url, sheet_name='Year 2010-2011')
df['InvoiceDate'] = pd.to_datetime(df['InvoiceDate'])
print(df.shape)
print(df.head(3))
# Check missing values in customer IDs
missing_customers = df['Customer ID'].isnull().sum()
print('Number of missing customer IDs:', missing_customers)
# Remove transactions that do not have a customer ID
df = df.dropna(subset=['Customer ID'])
print('Transactions remaining after cleaning:', df.shape[0])
# Quick sales aggregation by customer
df['Revenue'] = df['Price'] * df['Quantity']
customer_sales = df.groupby('Customer ID')['Revenue'].sum().reset_index()
customer_sales = customer_sales.sort_values(by='Revenue', ascending=False)
print(customer_sales.head(5))
# Find the number of unique customers
n_customers = df['Customer ID'].nunique()
print('Unique customers:', n_customers)
# Count purchases per customer
customer_freq = df.groupby('Customer ID')['Invoice'].nunique().reset_index()
customer_freq = customer_freq.rename(columns={'Invoice':'Num_Purchases'})
print(customer_freq.sort_values(by='Num_Purchases',ascending=False).head(5))
Intermediate Example: Average Order Value by Customer#
- Next, we will measure average order value (AOV) for each customer to find big-spenders and value-driven buyers.
- AOV is a key retail metric that influences marketing and loyalty programs.
- The formula is simple: Total revenue divided by number of unique orders for each customer.
# Compute average order value (AOV) per customer
aov_per_customer = customer_sales.merge(customer_freq, on='Customer ID')
aov_per_customer['AOV'] = aov_per_customer['Revenue'] / aov_per_customer['Num_Purchases']
print(aov_per_customer[['Customer ID','AOV']].sort_values('AOV',ascending=False).head())
# Segment customers by total revenue into quantiles
customer_sales['Segment'] = pd.qcut(customer_sales['Revenue'], q=4, labels=['Bronze','Silver','Gold','Platinum'])
print(customer_sales[['Customer ID','Revenue','Segment']].head(10))
Intermediate Example: Customer Recency#
- Recency analysis measures how recently a customer made their last purchase.
- It is common in RFM (Recency, Frequency, Monetary) segmentation.
- Recent buyers are often more likely to buy again soon.
# Calculate recency for each customer (in days)
latest_date = df['InvoiceDate'].max()
recency = df.groupby('Customer ID')['InvoiceDate'].max().reset_index()
recency['RecencyDays'] = (latest_date - recency['InvoiceDate']).dt.days
print(recency[['Customer ID','RecencyDays']].sort_values('RecencyDays').head())
# Merge RFM metrics for one-table customer view
rfm = customer_sales.merge(customer_freq, on='Customer ID').merge(recency[['Customer ID','RecencyDays']], on='Customer ID')
print(rfm.head())
# Advanced: k-means clustering for customer segmentation
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
X = rfm[['Revenue','Num_Purchases','RecencyDays']]
X_scaled = StandardScaler().fit_transform(X)
kmeans = KMeans(n_clusters=4, random_state=42)
rfm['Cluster'] = kmeans.fit_predict(X_scaled)
print(rfm[['Customer ID','Revenue','Num_Purchases','RecencyDays','Cluster']].head())
# Advanced: Profile each customer cluster
cluster_profile = rfm.groupby('Cluster').agg({'Revenue':'mean','Num_Purchases':'mean','RecencyDays':'mean','Customer ID':'count'}).rename(columns={'Customer ID':'Num_Customers'})
print(cluster_profile)
# Error handling: What if a groupby fails due to a missing column?
try:
rfm.groupby('MissingColumn').mean()
except KeyError as e:
print('Error:', e)
# Debugging: Make sure revenue is always non-negative
bad_revenue = df[df['Revenue'] < 0]
print('Transactions with negative revenue:', bad_revenue.shape[0])
# Remove transactions with negative revenue for clean analysis
df = df[df['Revenue'] >= 0]
print('Transactions after removing negatives:', df.shape[0])
Best Practices in Retail Customer Segmentation#
- Segment by buying behavior, not only demographics.
- Combine RFM (Recency, Frequency, Monetary) metrics for deeper insight.
- Remove or separately analyze returns and incomplete transactions for accuracy.
- Regularly update segments as customers' behaviors change.
# Tiny End-to-End Problem: Identify VIP Customers
vip = customer_sales[customer_sales['Segment']=='Platinum']
print('Number of Platinum (VIP) customers:', vip.shape[0])
print(vip[['Customer ID','Revenue']].head(10))
# Bonus: Export VIP list for the marketing team
vip[['Customer ID','Revenue']].to_csv('vip_customers.csv', index=False)
print('VIP customer list exported to vip_customers.csv')
Lesson Summary#
- You learned how to segment customers based on order data and RFM metrics.
- You saw how clustering can automatically group customers by behavioral traits.
- You practiced handling missing or incorrect data for robust analysis.
- These segmentation skills help grow retail revenue and improve customer loyalty.
Found this useful?
All lessons, notebooks and datasets here are free. If they helped you, a coffee keeps new lessons coming.



