Q&A library Python

How do I format numbers in a DataFrame for presentation in pandas?

Python Advanced formattingpresentationstyler

Short answer

Use the Styler through df.style.format to control how numbers are displayed without changing the underlying values. Formatting for display and rounding the data are different things, and only one is safe.

The short version

Use df.style.format(...) to control how values are displayed without altering them. This keeps full precision in the data while showing a clean table. Rounding the actual values with df.round() changes your data and should be avoided until the very end, if at all.

Formatting for display

import pandas as pd

df = pd.DataFrame({
    "city": ["Leeds", "Bath"],
    "amount": [1234.5678, 987.6543],
    "share": [0.1234, 0.8766],
})

styled = df.style.format({
    "amount": "{:,.2f}",     # thousands separator, two decimals
    "share": "{:.1%}",       # as a percentage
})

The amount now displays as 1,234.57 and share as 12.3%, while the stored numbers keep their full precision.

Why this matters more than it seems

Rounding your data to make it look nice destroys information and compounds errors. If you round to two decimals and then sum, the total can differ from the sum of the unrounded values. Formatting affects only the presentation layer, so every calculation still uses the exact numbers and only the final display is tidy.

The rule: round for the eye, never for the maths.

Highlighting values

The Styler can also apply conditional formatting, which is useful for drawing attention in a report.

df.style.format({"amount": "{:,.2f}"}) \
        .highlight_max(subset=["amount"], color="lightgreen") \
        .bar(subset=["share"], color="lightblue")

highlight_max shades the largest value, and bar draws in-cell bars proportional to the value, which conveys the distribution at a glance.

Hiding the index

The default integer index is rarely meaningful in a presented table.

df.style.hide(axis="index")

Where it renders

The Styler produces HTML, so it displays in a notebook and can be exported.

styled.to_html("report.html")
styled.to_excel("report.xlsx")     # formatting carries into Excel

It does not affect a plain print(df) in a terminal, which shows the raw values. So the Styler is a tool for notebooks, HTML reports and Excel output, not for console scripts.

Keep the data and the presentation separate

The broader principle is worth holding on to. Your DataFrame is data: exact, unformatted, suitable for computation. The formatted table is a view of it, produced at the end for a human. Mixing the two, by storing formatted strings in the frame, is a common mistake that turns numbers into text and silently breaks every subsequent calculation.

df["amount"] = df["amount"].map("{:,.2f}".format)   # DON'T: now it is text
df["amount"].sum()   # fails or concatenates, because these are strings now

Format at the boundary, and keep the numbers as numbers everywhere else.

Need this solved on your own data?

The library is free and always will be. When the problem is bigger than an answer, we take on the work.

Start a project