Three levers and one summary metric
The DA2 course laid out the decomposition of an online store’s revenue:
revenue = sessions x conversion rate x average order value
To compare segments, a fourth metric is very useful: revenue per visit (RPV), that is, revenue divided by the number of sessions. It combines the store’s two own levers:
RPV = revenue / sessions = conversion rate x average order value
By device
traffic["conversion"] = traffic["orders"] / traffic["sessions"]
traffic["aov"] = traffic["revenue"] / traffic["orders"] # average order value
traffic["rpv"] = traffic["revenue"] / traffic["sessions"]
| Device | Sessions | Conversion | Average order value | RPV |
|---|---|---|---|---|
| mobile | 6,000 | 1.5% | €60 | €0.90 |
| desktop | 3,000 | 3.2% | €90 | €2.88 |
| tablet | 1,000 | 2.4% | €70 | €1.68 |
Mobile brings 60% of visits but only 34% of revenue: each mobile visit earns three times less than a desktop visit. Gaining half a percentage point of conversion on mobile would be worth 6,000 x 0.005 x 60 = 1,800 euros over the period.
Overall RPV is computed on the totals: 15,720 / 10,000 = 1.57 euros. The average of the three RPVs (1.82) would be wrong, because the segments do not have the same number of sessions.
The distribution of order values
The average order value summarizes a distribution that is often highly skewed: many small orders, a few very large ones.
print(amounts.mean()) # 69.44
print(amounts.median()) # 47.50
print(amounts.max()) # 420 : an exceptional order
A single 420-euro order (a business customer? a data entry error?) pushes the mean more than 20 euros above the median. Before commenting on a rise in average order value, look at the median and the largest orders. If they belong to a different business (professional purchases), handle them in a separate segment rather than deleting them.
The free-shipping threshold
Many stores offer free delivery above a certain amount. Customers adjust their baskets: you often see a buildup of orders just above the threshold, and sometimes orders stuck just below it.
near = amounts.between(free_shipping_threshold - 10, free_shipping_threshold, inclusive="left")
print(near.mean()) # share of orders between 40 and 50 euros
inclusive="left" includes 40 and excludes 50. Here, 44% of orders fall within 10 euros below the threshold: a complementary product suggestion under 10 euros could push them over. But beware: lowering the threshold or adding a suggestion also changes margin and the behavior of other customers. The effect is measured with an A/B test (courses MK1 and ST3), not with a simple projection.
Reading the metrics together
The three levers interact. An aggressive promotion can increase conversion and lower the average order value; a traffic increase from a poorly targeted campaign often lowers conversion. That is why RPV and total revenue are read together with the levers, and always on the same definition of sessions and orders (validated orders, excluding cancellations, with or without tax specified).
Key takeaways
- RPV = revenue / sessions = conversion x average order value; it compares segments.
- Overall ratios on sums, never as an average of ratios.
- Look at the median and extreme values before commenting on the average order value.
Exercises
Solutions and tests stay on the server. In the student space, your code is run and checked, and the tutor gives hints before the solution.
Conversion, order value and RPV
Add the columns
conversion,aovandrpvtotraffic. Computeglobal_rpvon the totals,best_device(the device with the highest RPV) andmobile_gain: the additional revenue if mobile conversion rose by 0.5 point at constant average order value.import pandas as pd traffic = pd.DataFrame({ "device": ["mobile", "desktop", "tablet"], "sessions": [6000, 3000, 1000], "orders": [90, 96, 24], "revenue": [5400.0, 8640.0, 1680.0], }).set_index("device") # global_rpv = ... # best_device = ... # mobile_gain = ...Order value distribution
From
amounts, computemean_value,median_value,mean_without_max(mean without the largest order) andnear_threshold_share: the share of orders in [threshold - 10; threshold[.import pandas as pd amounts = pd.Series([22, 35, 41, 44, 47, 48, 49, 52, 55, 60, 75, 38, 46, 49, 30, 420], name="order_value") free_shipping_threshold = 50 # mean_value = ... # median_value = ... # mean_without_max = ... # near_threshold_share = ...Reading RPV
Channel A converts at 4% with a 30-euro order value; channel B converts at 2% with a 75-euro order value. Which channel earns more per visit?
- A, because it converts twice as well
- B: 1.50 euros per visit versus 1.20 for A
- They are equal
- Impossible to say without the number of sessions
End-of-lesson quiz
10,000 sessions, 250 orders, 15,000 euros of revenue. RPV?
- 60 euros
- 1.50 euros
- 2.5%
Why present the median order value next to the mean?
- Because the mean is sensitive to exceptional large orders
- Because the median is always higher
- Out of habit
Many orders between 40 and 49 euros for a free-shipping threshold of 50 euros. What should you do?
- Lower the threshold immediately
- Form a hypothesis (complementary product suggestion) and test it
- Remove free shipping
The rest of the course
- Retention and repurchase: delays between orders and maturity15 min
- Cohort analysis: retention and revenue by arrival month20 min
- Recommendations: products bought together18 min
- Store dashboard and RFM segmentation15 min