Mathew K Analytics

Lesson 1 · Python for Retail E-commerce Analytics

Introduction to Retail and E-commerce Analytics with Python

In this lesson, you will learn how to analyze retail and e-commerce data using Python. You will solve real-world problems such as finding top-selling…

⬇ Download notebookOpen in Colab ↗

What you'll learn

Data

No separate download needed — the notebook creates or downloads everything it uses.

📓 Full notebook

Download .ipynb

Introduction to Retail and E-commerce Analytics#

  • In this lesson, you will learn how to analyze retail and e-commerce data using Python.
  • You will solve real-world problems such as finding top-selling products, analyzing customer behavior, and understanding sales trends.
  • Retail analytics helps businesses make better sales, marketing, and inventory decisions by turning raw transactions into actionable insights.
  • By the end, you will know how to extract key metrics from real datasets to support retail business decisions.
import pandas as pd
import numpy as np
import warnings
warnings.filterwarnings('ignore')

Core Concepts in Retail Analytics#

  • Retail datasets usually contain information about transactions, products, customers, and orders.
  • Important business metrics include revenue (sales), quantity sold, price, and product categories.
  • Common beginner mistakes include confusing order-level and item-level analysis, using incorrect groupings, or miscalculating revenue.
  • Understanding the structure of retail data is the first step to reliable business insights.
# Load online retail transactions dataset from UCI repository
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/00502/online_retail_II.xlsx'
df_transactions = pd.read_excel(url, sheet_name='Year 2010-2011')
df_transactions['InvoiceDate'] = pd.to_datetime(df_transactions['InvoiceDate'])
print(df_transactions.shape)
print(df_transactions.head(3))
(541910, 8)
  Invoice StockCode                         Description  Quantity  \
0  536365    85123A  WHITE HANGING HEART T-LIGHT HOLDER         6   
1  536365     71053                 WHITE METAL LANTERN         6   
2  536365    84406B      CREAM CUPID HEARTS COAT HANGER         8   

          InvoiceDate  Price  Customer ID         Country  
0 2010-12-01 08:26:00   2.55      17850.0  United Kingdom  
1 2010-12-01 08:26:00   3.39      17850.0  United Kingdom  
2 2010-12-01 08:26:00   2.75      17850.0  United Kingdom  
# Example 1: Compute basic statistics for transaction quantities
print('Mean Quantity Sold:', df_transactions['Quantity'].mean())
print('Min Quantity Sold:', df_transactions['Quantity'].min())
print('Max Quantity Sold:', df_transactions['Quantity'].max())
Mean Quantity Sold: 9.552233765754462
Min Quantity Sold: -80995
Max Quantity Sold: 80995
# Example 2: Total revenue by summing Quantity * Price
df_transactions['Revenue'] = df_transactions['Quantity'] * df_transactions['Price']
total_revenue = df_transactions['Revenue'].sum()
print('Total Revenue in dataset:', round(total_revenue,2))
Total Revenue in dataset: 9747765.93
# Example 3: Count number of unique customers
n_customers = df_transactions['Customer ID'].nunique()
print('Number of unique customers:', n_customers)
Number of unique customers: 4372
# Load synthetic product catalog data
np.random.seed(42)
categories = ['Electronics','Clothing','Home','Sports','Beauty']
product_ids = list(range(1001,1101))
product_categories = np.random.choice(categories,100)
product_prices = np.round(np.random.uniform(5,500,100),2)
df_products = pd.DataFrame({'ProductID':product_ids,'Category':product_categories,'Price':product_prices})
print(df_products.shape)
print(df_products.head(3))
(100, 3)
   ProductID Category   Price
0       1001   Sports  457.91
1       1002   Beauty  425.77
2       1003     Home  227.48
# Example 4: Compute average price by product category
mean_price_by_cat = df_products.groupby('Category')['Price'].mean()
print('Average price per category:')
print(mean_price_by_cat)
Average price per category:
Category
Beauty         288.031053
Clothing       234.480952
Electronics    237.017222
Home           255.382500
Sports         223.306538
Name: Price, dtype: float64
# Load synthetic customer orders dataset
np.random.seed(42)
n_orders = 1000
order_ids = list(range(1, n_orders+1))
customer_ids = np.random.randint(1000,1500,n_orders)
product_ids_orders = np.random.randint(1001,1100,n_orders)
quantities = np.random.randint(1,5,n_orders)
order_dates = pd.date_range('2023-01-01', periods=n_orders, freq='h')
df_orders = pd.DataFrame({'OrderID':order_ids,'CustomerID':customer_ids,'ProductID':product_ids_orders,'Quantity':quantities,'OrderDate':order_dates})
print(df_orders.shape)
print(df_orders.head(3))
(1000, 5)
   OrderID  CustomerID  ProductID  Quantity           OrderDate
0        1        1102       1049         3 2023-01-01 00:00:00
1        2        1435       1011         1 2023-01-01 01:00:00
2        3        1348       1085         3 2023-01-01 02:00:00
# Example 5: Find the most frequently ordered product
top_product = df_orders['ProductID'].mode()[0]
print('Most ordered product ID:', top_product)
Most ordered product ID: 1026
# Example 6: Orders per customer - finding loyal customers
order_counts = df_orders.groupby('CustomerID')['OrderID'].count()
top_customers = order_counts.sort_values(ascending=False).head(5)
print('Top 5 most loyal customers (by number of orders):')
print(top_customers)
Top 5 most loyal customers (by number of orders):
CustomerID
1098    8
1143    7
1251    6
1372    6
1232    6
Name: OrderID, dtype: int64
# Intermediate Example 1: Weekly order trends
df_orders['Week'] = df_orders['OrderDate'].dt.isocalendar().week
weekly_orders = df_orders.groupby('Week')['OrderID'].count()
print('Orders per week:')
print(weekly_orders.head())
Orders per week:
Week
1    168
2    168
3    168
4    168
5    168
Name: OrderID, dtype: int64
# Intermediate Example 2: Merge orders with product catalog for category analysis
df_merged = pd.merge(df_orders, df_products, how='left', left_on='ProductID', right_on='ProductID')
cat_sales = df_merged.groupby('Category')['Quantity'].sum().sort_values(ascending=False)
print('Total quantity sold by category:')
print(cat_sales)
Total quantity sold by category:
Category
Sports         685
Clothing       511
Beauty         487
Electronics    408
Home           399
Name: Quantity, dtype: int32
# Intermediate Example 3: Average order value (AOV) calculation
df_merged['OrderValue'] = df_merged['Quantity'] * df_merged['Price']
aov = df_merged.groupby('OrderID')['OrderValue'].sum().mean()
print('Average Order Value (AOV):', round(aov, 2))
Average Order Value (AOV): 593.73
# Advanced Example 1: Identify returning vs. one-time customers
customer_orders_count = df_orders.groupby('CustomerID')['OrderID'].count()
returning = (customer_orders_count > 1).sum()
one_time = (customer_orders_count == 1).sum()
print('Returning customers:', returning)
print('One-time customers:', one_time)
Returning customers: 282
One-time customers: 141
# Advanced Example 2: Quick cohort analysis by customer first purchase week
df_orders['FirstOrderWeek'] = df_orders.groupby('CustomerID')['OrderDate'].transform('min').dt.isocalendar().week
cohort_sizes = df_orders.groupby('FirstOrderWeek')['CustomerID'].nunique()
print('Cohort sizes by first purchase week:')
print(cohort_sizes.head())
Cohort sizes by first purchase week:
FirstOrderWeek
1    135
2     91
3     65
4     53
5     40
Name: CustomerID, dtype: int64
# Advanced Example 3: Find peak sales hour
df_orders['Hour'] = df_orders['OrderDate'].dt.hour
hourly_sales = df_orders.groupby('Hour')['Quantity'].sum()
peak_hour = hourly_sales.idxmax()
print('Peak hour for sales:', peak_hour)
Peak hour for sales: 5
# Error Example 1: Handling missing or null values in customer ID
missing_customers = df_transactions['Customer ID'].isnull().sum()
print('Number of transactions missing customer ID:', missing_customers)
Number of transactions missing customer ID: 135080
# Error Example 2: Incorrect revenue by grouping only on product
incorrect_revenue = df_merged.groupby('ProductID')['OrderValue'].sum()
print('Total Revenue by Product:')
print(incorrect_revenue.head(3))
Total Revenue by Product:
ProductID
1001    14195.21
1002     8515.40
1003     7506.84
Name: OrderValue, dtype: float64
# Error Example 3: Common bug - using sum instead of mean for order value
wrong_aov = df_merged['OrderValue'].sum()
print('Wrong AOV (sum, not mean):', wrong_aov)
Wrong AOV (sum, not mean): 593731.24

Best Practices in Retail Analytics#

  • Segmenting customers helps businesses design loyalty programs and increase retention.
  • Analyzing product performance by category reveals strengths and weaknesses in assortment.
  • Market basket analysis can uncover product combinations often bought together.
  • Demand forecasting and seasonal trend analysis help meet customer needs without overstocking.
  • Always check for missing or outlier data before making business decisions.
# Market basket pattern: Find most common product pairs in baskets
market_products = ['Bread','Milk','Butter','Eggs','Apples','Chicken','Rice','Cheese']
transaction_ids = np.repeat(np.arange(1,301),3)
product_choices = np.random.choice(market_products, len(transaction_ids))
df_basket = pd.DataFrame({'TransactionID':transaction_ids,'Product':product_choices})
basket_pairs = (df_basket.groupby('TransactionID')['Product'].apply(lambda x: tuple(sorted(x)))
                .value_counts().head(5))
print('Most common product combinations (top 5):')
print(basket_pairs)
Most common product combinations (top 5):
Product
(Apples, Bread, Eggs)      9
(Apples, Apples, Milk)     7
(Eggs, Milk, Rice)         6
(Cheese, Chicken, Milk)    6
(Cheese, Eggs, Rice)       6
Name: count, dtype: int64
# Product performance pattern: Top 3 categories by total revenue
df_merged['Revenue'] = df_merged['Quantity'] * df_merged['Price']
category_revenue = df_merged.groupby('Category')['Revenue'].sum().sort_values(ascending=False)
print('Top 3 categories by revenue:')
print(category_revenue.head(3))
Top 3 categories by revenue:
Category
Sports      147783.07
Beauty      134105.61
Clothing    121487.00
Name: Revenue, dtype: float64
# Simple demand forecasting: Monthly sales trend for top category
top_cat = category_revenue.idxmax()
cat_df = df_merged[df_merged['Category'] == top_cat]
cat_df['Month'] = cat_df['OrderDate'].dt.to_period('M')
monthly_sales = cat_df.groupby('Month')['Revenue'].sum()
print(f'Monthly revenue trend for top category ({top_cat}):')
print(monthly_sales)
Monthly revenue trend for top category (Sports):
Month
2023-01    117100.34
2023-02     30682.73
Freq: M, Name: Revenue, dtype: float64
# END-TO-END PROBLEM: Identify top 5 high value customers
df_merged['CustomerRevenue'] = df_merged.groupby('CustomerID')['OrderValue'].transform('sum')
top5_customers = df_merged[['CustomerID','CustomerRevenue']].drop_duplicates().sort_values('CustomerRevenue',ascending=False).head(5)
print('Top 5 high value customers:')
print(top5_customers)
Top 5 high value customers:
     CustomerID  CustomerRevenue
163        1098          5808.86
89         1053          5621.52
488        1222          4999.08
123        1379          4952.56
195        1095          4803.94
 

Found this useful?

All lessons, notebooks and datasets here are free. If they helped you, a coffee keeps new lessons coming.