Lesson 25 · Python for Retail E-commerce Analytics
Master Interpreting Retail Performance Patterns Using Python for E-commerce Analytics
In this lesson, we will solve real-world retail analytics problems by interpreting sales patterns and customer behavior in transactional data. Understanding…
- CoursePython for Retail E-commerce Analytics
- Lesson25 of 43
- Video24 min
- FormatJupyter notebook · 19 code cells
What you'll learn
- Retail Data: Concepts and Common Pitfalls
- Beginner Example 1: Calculating Total Sales Revenue
- Beginner Example 2: Counting Number of Orders
- Beginner Example 3: Identifying Top-Selling Products
- Intermediate Example 1: Analyzing Average Order Value (AOV)
- Intermediate Example 2: Sales by Country
- Intermediate Example 3: Monthly Sales Patterns
- Advanced Example 1: Identifying High-Value Customers
Data
No separate download needed — the notebook creates or downloads everything it uses.
📓 Full notebook
Download .ipynbInterpreting Retail Performance Patterns#
- In this lesson, we will solve real-world retail analytics problems by interpreting sales patterns and customer behavior in transactional data.
- Understanding sales and performance patterns helps retail businesses improve inventory management, marketing strategies, and profitability.
- We will use real e-commerce datasets to uncover actionable insights such as top-performing products, customer segments, and time-based sales trends.
- By the end, you will be able to turn raw transactional data into clear business recommendations.
import pandas as pd
import numpy as np
import warnings
warnings.filterwarnings('ignore')
Retail Data: Concepts and Common Pitfalls#
- Retail datasets often describe transactions, orders, products, and customers.
- Each row of a transactions dataset typically corresponds to a product sold in an order.
- Key sales metrics include quantity (how many sold), price (unit price), and revenue (quantity x price).
- Beginners often confuse product-level and order-level metrics, mix up gross and net revenue, or forget time granularity.
- Careful grouping and aggregation is essential for interpreting performance patterns correctly.
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))
Beginner Example 1: Calculating Total Sales Revenue#
- The first step to interpreting retail patterns is to calculate total sales revenue.
- Revenue for each row is given by Quantity x Price.
- Total sales revenue is the sum of this value across all transactions.
df['Revenue'] = df['Quantity'] * df['Price']
total_revenue = df['Revenue'].sum()
print(f'Total sales revenue: \u00a3{total_revenue:,.2f}')
Beginner Example 2: Counting Number of Orders#
- Retailers care about how many unique orders they receive in a period.
- Each unique Invoice number typically represents one order.
- Counting unique invoice numbers gives us the total number of orders.
num_orders = df['Invoice'].nunique()
print(f'Number of unique orders: {num_orders}')
Beginner Example 3: Identifying Top-Selling Products#
- Top-selling products are those with the highest quantity sold across all orders.
- Summing quantity by product description reveals which products are most popular.
top_products = df.groupby('Description')['Quantity'].sum().sort_values(ascending=False).head(5)
print('Top 5 products by total quantity sold:')
print(top_products)
Intermediate Example 1: Analyzing Average Order Value (AOV)#
- A key metric in e-commerce is average order value: total sales revenue divided by the number of orders.
- AOV helps businesses understand customer spending behavior.
aov = total_revenue / num_orders
print(f'Average order value (AOV): \u00a3{aov:,.2f}')
Intermediate Example 2: Sales by Country#
- Retailers often sell to multiple countries, and country-wise analysis highlights key markets.
- Summing revenue per country shows which regions contribute most to sales.
sales_by_country = df.groupby('Country')['Revenue'].sum().sort_values(ascending=False).head(5)
print('Top 5 countries by sales revenue:')
print(sales_by_country)
Intermediate Example 3: Monthly Sales Patterns#
- Businesses often want to know how sales change over time.
- Summing revenue by month can highlight seasonal or trending patterns.
df['Month'] = df['InvoiceDate'].dt.to_period('M')
monthly_sales = df.groupby('Month')['Revenue'].sum()
print('Sales by month:')
print(monthly_sales.round(2))
Advanced Example 1: Identifying High-Value Customers#
- Not all customers contribute equally to sales revenue.
- Finding customers who spend the most can help with VIP marketing and retention.
top_customers = df.groupby('Customer ID')['Revenue'].sum().sort_values(ascending=False).head(5)
print('Top 5 customers by revenue:')
print(top_customers)
Advanced Example 2: Product Category Analysis (Synthetic Catalog)#
- Sometimes, you will need to join transactions to product catalog data for richer analysis.
- Let us create a synthetic product catalog and analyze which category drives most revenue.
# Create synthetic catalog
np.random.seed(42)
categories = ['Electronics','Clothing','Home','Sports','Beauty']
stock_codes = df['StockCode'].dropna().unique()
random_categories = np.random.choice(categories, size=len(stock_codes))
catalog = pd.DataFrame({'StockCode': stock_codes, 'Category': random_categories})
# Join to main data
df_cat = pd.merge(df, catalog, on='StockCode', how='left')
# Aggregate revenue per category
category_revenue = df_cat.groupby('Category')['Revenue'].sum().sort_values(ascending=False)
print('Revenue by product category:')
print(category_revenue)
Advanced Example 3: Time-Based Sales Growth Rate#
- Measuring percent change in monthly revenue shows sales growth or decline over time.
- Growth rate helps managers react quickly to performance trends.
monthly_growth = monthly_sales.pct_change().dropna() * 100
print('Monthly sales growth rate (percentage):')
print(monthly_growth.round(2))
Error Handling: Dealing With Missing Customer IDs#
- Real retail data often have missing or invalid customer IDs.
- Ignoring missing customer IDs in customer-level analysis can mislead your conclusions.
missing_customers = df['Customer ID'].isnull().sum()
total_transactions = len(df)
missing_pct = 100 * missing_customers / total_transactions
print(f'Missing customer IDs: {missing_customers} ({missing_pct:.1f}% of transactions)')
Error Handling: Correcting Incorrect Aggregations#
- Summing price instead of revenue is a common mistake.
- Always multiply quantity by price before summing for transaction-level revenue.
# Incorrect aggregation: sum of price column
wrong_total = df['Price'].sum()
print(f'Incorrect total by summing Price only: \u00a3{wrong_total:,.2f}')
# Correct total revenue is much higher
print(f'Correct total revenue: \u00a3{total_revenue:,.2f}')
Error Example: Incorrect Product or Category Grouping#
- Failing to use the correct field to group by can mix up products or categories.
- Always verify that grouping columns are uniquely identifying the product or category.
# Example: Group by 'StockCode' vs. 'Description'
group_by_code = df.groupby('StockCode')['Revenue'].sum().sort_values(ascending=False).head(3)
group_by_desc = df.groupby('Description')['Revenue'].sum().sort_values(ascending=False).head(3)
print('Grouped by StockCode:')
print(group_by_code)
print('\nGrouped by Description:')
print(group_by_desc)
Best Practice: Customer Segmentation#
- Segmenting customers by spending can help tailor marketing or loyalty efforts.
- Use quantiles to group customers into tiers based on total revenue.
customer_revenue = df.groupby('Customer ID')['Revenue'].sum()
segments = pd.qcut(customer_revenue, q=4, labels=['Bronze','Silver','Gold','Platinum'])
segment_counts = segments.value_counts()
print('Customer segmentation by revenue tier:')
print(segment_counts)
Best Practice: Product Performance Analysis#
- Always compare both total quantity sold and total revenue by product.
- Some products are bestsellers by volume but not by revenue (and vice versa).
product_performance = df.groupby('Description').agg({'Quantity':'sum','Revenue':'sum'})
print('Sample product performance rows:')
print(product_performance.sort_values('Quantity', ascending=False).head(3))
print(product_performance.sort_values('Revenue', ascending=False).head(3))
Best Practice: Detecting Seasonal Trends#
- Identifying months with sales peaks or dips guides promotional campaigns.
- Overlaying category or product sales by month can reveal product-specific seasonality.
# Example: Category revenue by month
df_cat['Month'] = df_cat['InvoiceDate'].dt.to_period('M')
cat_month = df_cat.groupby(['Category','Month'])['Revenue'].sum().unstack(0).fillna(0)
print('Revenue by category and month (sample):')
print(cat_month.head())
End-to-End Example: From Transactions to Business Insight#
- Let us answer a critical retail question: Which product category should the business prioritize for upcoming promotions?
- We will combine revenue totals and seasonality to make a clear recommendation.
# Step 1: Find top revenue-driving category
top_category = category_revenue.idxmax()
print(f'Top category by total revenue: {top_category}')
# Step 2: Find peak month for this category
cat_peak_month = cat_month[top_category].idxmax()
print(f'Peak sales month for {top_category}: {cat_peak_month}')
Found this useful?
All lessons, notebooks and datasets here are free. If they helped you, a coffee keeps new lessons coming.



