Before this: Fit on training data only
The idea
An average over 40% of the rows is not the same as an average over all rows. Readers can't tell unless you say so.
Next to each key number, report the count it is based on, how many rows were missing or excluded, and why.
When coverage differs between groups, comparisons between those groups can mislead; call it out.
Worked example
Input: duration_min: 10, (missing), 30, (missing)
- Visual
Add step → Group and total → avg(duration_min), count(duration_min), count rows
- SQL (DuckDB)
SELECT AVG(d), COUNT(d), COUNT(*) FROM visits
- pandas
df["d"].agg(["mean", "count"]), len(df)
Result: Average 20 minutes based on 2 of 4 visits
Common mistakes
- Averages without counts.
- Filling gaps to make coverage look complete.
- Comparing groups with very different coverage.
Check yourself
What two counts should accompany an average?
The number of values it is based on and the total number of rows (or how many were missing).
Practice it
Label unknown categories and keep missing numbers missing.
Next: Label unknown categories, keep missing numbers missing