Formatting Numbers
Overview
Round at the end, and show the precision you actually have.
What You Will Learn in This Lesson
By the end of this lesson, you will be able to:
- Round for display without rounding during the calculation.
- Say what a number of decimal places claims.
- Format a percentage and a large number readably.
- Report the middle with the spread beside it.
Why This Matters
Rounding early puts error into every step that follows; rounding late and too finely claims a precision the data never had. Nine observations do not support four decimal places, and printing them anyway tells a reader the answer is more certain than it is.
Step 1: Round for the reader, not for the maths
Keep full precision through the calculation and round once, at the point where a person sees it.
What early rounding costs
Rounding each value before averaging is a different calculation from averaging then rounding, and on enough rows the difference is visible.
import pandas as pd
s = pd.Series([1.25, 1.25, 1.25, 1.25])
print(round(float(s.mean()), 1))
print(round(float(s.round(1).mean()), 1))
Formatting, which is not rounding
An f-string formats for display and leaves the value alone. That is usually what you want: the stored number stays exact and only the printed one is shortened.
import pandas as pd
value = 1234567.891
print(f"{value:,.0f}")
print(f"{value:.2f}")
share = 0.0734
print(f"{share:.1%}")
Mini Practice #1: Round late
Try It YourselfAverage these both ways — rounding first, and rounding last — and see which one is right.
Step 2: Precision is a claim
Each decimal place you print says "I know the answer this precisely". With nine observations, you do not.
What the extra digits mean
72.4183 over nine rows is noise dressed as certainty. One decimal place is usually generous for a mean of a small sample.
import pandas as pd
small = pd.Series([70, 72, 75, 68, 80, 71, 73, 69, 74])
print(len(small), "observations")
print(small.mean())
print(round(float(small.mean()), 1))
The middle needs its spread
A mean on its own hides how much the values vary. Reporting the minimum and maximum beside it costs one line and stops a wide spread being read as a tight one.
import pandas as pd
tight = pd.Series([70.0, 71.0, 72.0])
wide = pd.Series([10.0, 71.0, 132.0])
for s in (tight, wide):
print(f"mean {s.mean():.1f} (min {s.min():.1f}, max {s.max():.1f})")
Both have a mean of 71. Only one of them supports the sentence "they scored about 71".
Mini Practice #2: Two series, one mean
Try It YourselfPrint the mean, minimum and maximum of both. They share a mean and should not share a sentence.
Step 3: When to Use It
The number a reader sees
Round once, at the end, to the precision the data supports.
f"{mean:.1f}%"
Large and small values
Thousands separators and percentages make a figure readable at a glance.
When Not to Use It
Do not round values on the way in and then compute with them. Small rounding errors add up — round only the final answer.
End-of-Lesson Exercises
Exercise 1: The middle, with its ends
Write summary_line(s) returning "mean 82.0 (min 70.0, max 95.0)" for a Series, every number to one decimal place.
Compute all three, round each to one place with float() so they print as plain numbers, and build the sentence with an f-string.
Exercise 2: Round once, at the end
Write mean_to(s, places) returning the mean of the Series rounded to places decimal places — rounding only the final answer, never the values on the way in.
Take s.mean() at full precision, then round once. Calling s.round(places) first would round every value before averaging, which is a different calculation.