diff --git a/doc/source/whatsnew/v0.24.0.rst b/doc/source/whatsnew/v0.24.0.rst index 4ff3cc728f7f7..0fad0dc65edaa 100644 --- a/doc/source/whatsnew/v0.24.0.rst +++ b/doc/source/whatsnew/v0.24.0.rst @@ -1395,6 +1395,7 @@ Notice how we now instead output ``np.nan`` itself instead of a stringified form - Bug in :meth:`read_excel()` in which extraneous header names were extracted, even though none were specified (:issue:`11733`) - Bug in :meth:`read_excel()` in which ``index_col=None`` was not being respected and parsing index columns anyway (:issue:`20480`) - Bug in :meth:`read_excel()` in which ``usecols`` was not being validated for proper column names when passed in as a string (:issue:`20480`) +- :func:`DataFrame.to_string()`, :func:`DataFrame.to_html()`, :func:`DataFrame.to_latex()` will correctly format output when a string is passed as the ``float_format`` argument (:issue:`21625`, :issue:`22270`) Plotting ^^^^^^^^ diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index c777b89eeaf12..4c08ee89c33df 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -960,6 +960,8 @@ def __init__(self, *args, **kwargs): # float_format is expected to be a string # formatter should be used to pass a function if self.float_format is not None and self.formatter is None: + # GH21625, GH22270 + self.fixed_width = False if callable(self.float_format): self.formatter = self.float_format self.float_format = None diff --git a/pandas/tests/io/formats/data/gh21625_expected_output.html b/pandas/tests/io/formats/data/gh21625_expected_output.html new file mode 100644 index 0000000000000..a87e4ca301d9d --- /dev/null +++ b/pandas/tests/io/formats/data/gh21625_expected_output.html @@ -0,0 +1,14 @@ + + + + + + + + + + + + + +
x
00.200
\ No newline at end of file diff --git a/pandas/tests/io/formats/data/gh22270_expected_output.html b/pandas/tests/io/formats/data/gh22270_expected_output.html new file mode 100644 index 0000000000000..6694c43dc9e68 --- /dev/null +++ b/pandas/tests/io/formats/data/gh22270_expected_output.html @@ -0,0 +1,14 @@ + + + + + + + + + + + + + +
x
0100
\ No newline at end of file diff --git a/pandas/tests/io/formats/test_format.py b/pandas/tests/io/formats/test_format.py index 7d26ea05b514a..b974415ffb029 100644 --- a/pandas/tests/io/formats/test_format.py +++ b/pandas/tests/io/formats/test_format.py @@ -1359,6 +1359,18 @@ def test_to_string_float_formatting(self): '1 2.512000e-01') assert df_s == expected + def test_to_string_float_format_no_fixed_width(self): + + # GH 21625 + df = DataFrame({'x': [0.19999]}) + expected = ' x\n0 0.200' + assert df.to_string(float_format='%.3f') == expected + + # GH 22270 + df = DataFrame({'x': [100.0]}) + expected = ' x\n0 100' + assert df.to_string(float_format='%.0f') == expected + def test_to_string_small_float_values(self): df = DataFrame({'a': [1.5, 1e-17, -5.5e-7]}) diff --git a/pandas/tests/io/formats/test_to_html.py b/pandas/tests/io/formats/test_to_html.py index 0da48f60f1b51..882a629b5b706 100644 --- a/pandas/tests/io/formats/test_to_html.py +++ b/pandas/tests/io/formats/test_to_html.py @@ -465,3 +465,15 @@ def test_to_html_with_id(self): name='myindexname')) result = df.to_html(index_names=False, table_id="TEST_ID") assert ' id="TEST_ID"' in result + + def test_to_html_float_format_no_fixed_width(self, datapath): + + # GH 21625 + df = DataFrame({'x': [0.19999]}) + expected = expected_html(datapath, 'gh21625_expected_output') + assert df.to_html(float_format='%.3f') == expected + + # GH 22270 + df = DataFrame({'x': [100.0]}) + expected = expected_html(datapath, 'gh22270_expected_output') + assert df.to_html(float_format='%.0f') == expected diff --git a/pandas/tests/io/formats/test_to_latex.py b/pandas/tests/io/formats/test_to_latex.py index 73517890565c7..f55fa289ea085 100644 --- a/pandas/tests/io/formats/test_to_latex.py +++ b/pandas/tests/io/formats/test_to_latex.py @@ -708,3 +708,29 @@ def test_to_latex_multiindex_empty_name(self): \end{tabular} """ assert observed == expected + + def test_to_latex_float_format_no_fixed_width(self): + + # GH 21625 + df = DataFrame({'x': [0.19999]}) + expected = r"""\begin{tabular}{lr} +\toprule +{} & x \\ +\midrule +0 & 0.200 \\ +\bottomrule +\end{tabular} +""" + assert df.to_latex(float_format='%.3f') == expected + + # GH 22270 + df = DataFrame({'x': [100.0]}) + expected = r"""\begin{tabular}{lr} +\toprule +{} & x \\ +\midrule +0 & 100 \\ +\bottomrule +\end{tabular} +""" + assert df.to_latex(float_format='%.0f') == expected