Mastering Decimal Precision and Rounding in Python Tabulate

Control over decimal precision and rounding is essential when presenting numerical data.

In this tutorial, you’ll learn various methods to master decimal precision and rounding in Python tabulate.

 

 

Default precision behavior

When you use the tabulate module to display tabular data, it formats floating-point numbers with default precision.

from tabulate import tabulate
data = [
    ["Ahmed", 23.6789, 3.14159265],
    ["Fatima", 29.1234, 2.71828182]
]
headers = ["Name", "Value1", "Value2"]
print(tabulate(data, headers=headers))

Output:

Name      Value1    Value2
-------  --------  --------
Ahmed     23.6789   3.14159
Fatima    29.1234   2.71828

By default, tabulate displays floating-point numbers up to six decimal places, which might not align with your desired precision.

 

Specify precision for all numeric columns

You can control the precision of all numeric columns using the floatfmt parameter.

print(tabulate(data, headers=headers, floatfmt=".2f"))

Output:

Name      Value1    Value2
-------  -------  -------
Ahmed      23.68     3.14
Fatima     29.12     2.72

Setting floatfmt=".2f" formats all floating-point numbers to display with two decimal places.

 

Column-specific precision

To specify different precision levels for each numeric column, pass a list to the floatfmt parameter.

print(tabulate(data, headers=headers, floatfmt=["", ".3f", ".1f"]))

Output:

Name      Value1    Value2
-------  --------  -----
Ahmed     23.679    3.1
Fatima    29.123    2.7

By providing a list ["", ".3f", ".1f"], you set the precision for each column individually.

The first column uses the default formatting, the second displays three decimal places, and the third shows one.

 

Rounding Mechanisms

The default rounding in Python may not always align with significant figures due to floating-point representation.

number = 2.675
print(f"{number:.2f}")

Output:

2.67

Rounding 2.675 to two decimal places results in 2.67 instead of 2.68 because of binary floating-point approximation.

To achieve precise rounding, use the decimal module rounding modes along with tabulate.

def custom_floatfmt(value):
  if isinstance(value, float):
      d = Decimal(str(value))
      return f"{d.quantize(Decimal('.01'), rounding=ROUND_HALF_UP):.2f}"
  return value
formatted_data = [[custom_floatfmt(item) for item in row] for row in data]
print(tabulate(formatted_data, headers=headers))

Output:

Name      Value1    Value2
-------  -------  -------
Ahmed      23.68     3.14
Fatima     29.12     2.72

By using ROUND_HALF_UP, numbers like 2.675 correctly round to 2.68.

 

Handle scientific notation

To display very large or small numbers without scientific notation, adjust the floatfmt parameter.

large_data = [
    ["Hassan", 1.23e6, 9.876e-4],
    ["Mona", 4.56e7, 1.234e-5]
]
headers = ["Name", "LargeValue", "SmallValue"]
print(tabulate(large_data, headers=headers, floatfmt=".2f"))

Output:

Name      LargeValue    SmallValue
-------  -----------  -----------
Hassan   1230000.00         0.00
Mona    45600000.00         0.00

Using floatfmt=".2f" forces numbers into fixed-point notation but may round very small numbers to zero.

To preserve scientific notation, use an exponential format.

print(tabulate(large_data, headers=headers, floatfmt=".2e"))

Output:

Name      LargeValue    SmallValue
-------  -----------  -----------
Hassan    1.23e+06      9.88e-04
Mona      4.56e+07      1.23e-05

Formatting with .2e maintains scientific notation with two decimal places suitable for a wide range of magnitudes.

Leave a Reply

Your email address will not be published. Required fields are marked *