Cohort Analysis Explained with Examples
Cohort analysis explained with a worked example on real online shop transactions: grouping customers by the month they first bought, building a retention table in pandas, reading it along rows, columns and diagonals, and two traps it exposes: a cohort that only looks loyal and a spike that is really the calendar.
GloryTecks Team
Training & Placement Faculty
Last updated: 25 September 2026
A single retention number, such as "20% of customers came back", hides the most important question: is it getting better or worse? Customers who arrived in different months may behave very differently, and an overall average blends them together. Cohort analysis separates them. A cohort is a group of users who share a characteristic, most often the date they were acquired (Google Analytics: cohort exploration), and following each cohort over time shows whether newer customers stay better or worse than older ones.
This guide builds a retention table from a real UK online gift retailer's transactions (UCI: Online Retail) and shows how to read it, including two traps the example exposes.
Step 1: Assign every customer to a cohort
The cohort is the month of each customer's first purchase. Activity is recorded as one row per customer per month in which they bought, and the key column is the number of months since the cohort month:
import io
import urllib.request
import zipfile
import pandas as pd
url = "https://archive.ics.uci.edu/static/public/352/online+retail.zip"
with zipfile.ZipFile(io.BytesIO(urllib.request.urlopen(url).read())) as archive:
raw = pd.read_excel(archive.open("Online Retail.xlsx"), dtype={"InvoiceNo": str, "StockCode": str})
services = {"POST", "DOT", "M", "m", "C2", "D", "S", "B", "BANK CHARGES", "AMAZONFEE", "CRUK"}
sales = raw[~raw["InvoiceNo"].str.startswith("C") & ~raw["StockCode"].isin(services)
& ~raw["StockCode"].str.startswith("gift_") & (raw["Quantity"] > 0) & (raw["UnitPrice"] > 0)
& raw["CustomerID"].notna()]
active = pd.DataFrame({"customer": sales["CustomerID"].astype(int),
"month": sales["InvoiceDate"].dt.to_period("M")}).drop_duplicates()
active = active[active["month"] <= pd.Period("2011-11", "M")] # complete months only
active["cohort"] = active.groupby("customer")["month"].transform("min") # month of first purchase
active["months_since"] = (active["month"] - active["cohort"]).apply(lambda offset: offset.n)
print("customers first seen per month:",
active[active["months_since"] == 0].groupby("cohort").size().head(4).rename(index=str).to_dict())customers first seen per month: {'2010-12': 884, '2011-01': 416, '2011-02': 380, '2011-03': 452}Three preparation choices matter. Only purchases with a customer ID can be followed, so anonymous orders are excluded. Cancellations, postage and fees are removed, so "active" means a real purchase. And December 2011 is dropped because the data stops on 9 December, which would make that month look like a collapse.
Step 2: Build the retention table
Count the active customers in each cohort for each month since their first purchase, and divide by the cohort's size:
counts = active.groupby(["cohort", "months_since"])["customer"].nunique().unstack()
retention = counts.div(counts[0], axis=0)
print(retention.loc[:"2011-06", 0:5].round(2).to_string())months_since 0 1 2 3 4 5
cohort
2010-12 1.0 0.37 0.32 0.38 0.36 0.40
2011-01 1.0 0.22 0.27 0.23 0.32 0.29
2011-02 1.0 0.19 0.19 0.29 0.27 0.24
2011-03 1.0 0.15 0.25 0.20 0.22 0.17
2011-04 1.0 0.21 0.20 0.21 0.20 0.23
2011-05 1.0 0.19 0.17 0.17 0.21 0.23
2011-06 1.0 0.17 0.16 0.26 0.23 0.33Each row is a cohort; each column is a number of months after first purchase; each cell is the share of the cohort that bought in that month. Month 0 is always 100% by definition. This is "classic" or "N-month" retention: a customer counts in any month they are active, even after skipping months. Tools such as Mixpanel present the same idea as a retention report with one row per cohort (Mixpanel: retention).
Step 3: Read it three ways
Along a row: how one cohort behaves over time. The January cohort returns at 22% to 32% in each following month, a fairly stable core of repeat buyers rather than a steady decline.
Down a column: how cohorts compare at the same age. One month after their first purchase, 15% to 22% of the 2011 cohorts came back. If a column trends down over time, newer customers are worse at returning, an early warning that acquisition quality or the first experience is slipping. Here the column is broadly flat.
Along a diagonal: cells on the same diagonal fall in the same calendar month. The June cohort's month 5 is November, and it jumps to 33%. Extending the table beyond the columns shown, November is the best month after the first purchase for nine of the first ten cohorts. Calendar effects such as seasons, promotions or outages show up as diagonals, not rows.
Trap 1: the cohort that only looks loyal
The December 2010 cohort retains 32% to 40% every month, almost double the others. Before celebrating, ask how it was formed. The data starts on 1 December 2010, so "first purchase in December 2010" really means "first purchase we can see". That cohort includes every long-standing customer who happened to buy in December, not just new ones, and loyal customers naturally return more. It is also the largest cohort, 884 customers against 380 to 452 in the following months, another sign it is not a normal acquisition month. Exclude or flag any cohort that begins where your data begins.
Trap 2: the spike that is really the calendar
The June cohort's jump to 33% at month 5 is not a sign that June customers became more loyal in their fifth month. November is the pre-Christmas peak for a gift retailer, and every cohort active that month is lifted. Read diagonals before explaining spikes by cohort age, and compare like-for-like calendar months across years when you have them.
Choices that change the numbers
- Cohort definition: first purchase, sign-up, first use of a feature or a campaign. Choose the one tied to your question.
- Period length: days or weeks for apps used daily, months for shopping, quarters for business purchases.
- Retention definition: active in that exact period, as here, or still active in that period or any later one, often called unbounded or rolling retention. Say which you use.
- What counts as active: a purchase, a login, or a meaningful action. A login-based measure can look healthy while buying declines.
- Revenue cohorts: tracking revenue per original customer instead of counts shows whether returning customers also spend more.
Where cohorts fit
Cohort tables answer "do customers come back?" Funnels answer "where do users drop out on the way to converting?" and segmentation answers "which kinds of customers behave differently?" Used together, they explain most of what happens to customers after they arrive. Product analytics 101 shows how the three connect, and customer segmentation for analysts covers the third.
What is a good retention rate?
How is cohort analysis different from churn rate?
Can I do cohort analysis in Excel or SQL?
How many cohorts do I need?
Customer segmentation, business reporting and Python for data analysis are part of the Data Analytics course.
Sources
- Cohort exploration (Google Analytics Help) — Google Analytics Help
- Retention (Mixpanel documentation) — Mixpanel
- Online Retail (UCI Machine Learning Repository) — UCI Machine Learning Repository
GloryTecks Team
Training & Placement Faculty
The GloryTecks faculty team mentors learners across Data Science, AI and Data Engineering, with a focus on real-time projects and placement readiness in Hyderabad.
Want to master Data Analytics?
Join GloryTecks’ expert-led Data Analytics training in Hyderabad with real-time projects and 100% placement support.
Funnel Analysis: Measuring Conversion Step by Step
NextData Analytics Projects for Your Resume
Related articles
Excel for Data Analysis: Formulas That Matter
The Excel formulas that do most of the work in data analysis, shown as patterns on a sales table: looking up values with XLOOKUP, conditional totals with SUMIFS and COUNTIFS, cleaning text properly, handling errors without hiding problems, dynamic arrays with UNIQUE and FILTER, and readable formulas with LET.
Data Analyst Roadmap 2026: Skills, Tools and Timeline
A data analyst roadmap for 2026: the six stages to learn in order, from spreadsheets and SQL to BI tools, statistics and communication, what each stage should let you do, a realistic part-time timeline, a project that proves each stage, and how to tell when you are ready to apply for analyst roles.
Excel vs Power BI: Which Should You Learn First?
Should you learn Excel or Power BI first? For most beginners, a slice of Excel first, then Power Query and the data model, which Excel and Power BI share, and then Power BI. Here is why, what each tool teaches on its own, and which to start with in your situation.