A league table ranks entities by selected metrics so performance can be compared at a glance. At product level, it combines November and December revenue, sales volume, unique users, month-on-month differences, and conversion measures. section 4.4.2
Build a useful league table by:
- Separating purchase and cart events, because most metrics use purchases while conversion requires both event types. section 4.4.2
- Creating monthly indicator columns, grouping by product, and aggregating revenue, volume, and unique users. section 4.4.2
- Joining conversion metrics to the purchase table and checking that the resulting row count matches the number of products. section 4.4.2
- Choosing the ranking metric from the stakeholder question rather than assuming that one measure defines the best product. section 4.4.3
Finding December high performers
For a December sale analysis, compare month-on-month volume rather than relying only on absolute revenue. Calculate percentage change, inspect its distribution for outliers, exclude products with very low November volume, and separately handle products with no November sales. Then merge the selected products with catalog fields such as category, subcategory, and brand. section 4.4.3
Avoiding misleading conversion rankings
A product can appear to exceed 100% conversion when raw cart and purchase events do not support a straightforward interpretation. Inspect extreme records, then apply conversion bounds and minimum user and purchase thresholds before ranking high converters. section 4.4.3
league_table["volume_diff_pct"] = (
100 * (league_table["volume_diff"] / league_table["november_volume"])
)
fig, axis = plt.subplots()
(
league_table["volume_diff_pct"]
.replace([np.inf, -np.inf], np.nan)
.dropna()
.loc[lambda x: x.between(-101,501)]
.hist(bins=50, ax=axis)
)
axis.set(
title="Distribution of month-on-month percentage change in volume",
xlabel="% difference between sales in November and December",
ylabel="Frequency"
)
Calculate and plot percentage month-on-month volume change after replacing infinite values and removing missing results. section 4.4.3
