From bebe152871201ccbcac16ee0cf33806308674d69 Mon Sep 17 00:00:00 2001 From: Tom Neep Date: Mon, 13 Aug 2018 11:54:38 +0200 Subject: [PATCH 1/7] BUG: Fix float formatting when a string is passed as float_format arg Fixes GH21625 and GH22270 --- pandas/io/formats/format.py | 1 + pandas/tests/io/formats/test_format.py | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index 1ff0613876838..b805febd53b62 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -974,6 +974,7 @@ 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: + 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/test_format.py b/pandas/tests/io/formats/test_format.py index c19f8e57f9ae7..6dd059806499b 100644 --- a/pandas/tests/io/formats/test_format.py +++ b/pandas/tests/io/formats/test_format.py @@ -1328,6 +1328,12 @@ def test_to_string_float_formatting(self): '1 2.512000e-01') assert df_s == expected + df = DataFrame({'x': [0.19999, 100.0]}) + expected = ' x\n0 0.200\n1 100.000' + assert df.to_string(float_format='%.3f') == expected + expected = ' x\n0 0\n1 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]}) From bac5ee5d262c9753f69b28e4e62579f385b71fc5 Mon Sep 17 00:00:00 2001 From: Tom Neep Date: Mon, 13 Aug 2018 14:14:05 +0200 Subject: [PATCH 2/7] Put new float_format test cases into separate test --- pandas/tests/io/formats/test_format.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/pandas/tests/io/formats/test_format.py b/pandas/tests/io/formats/test_format.py index 6dd059806499b..4964ba15b6717 100644 --- a/pandas/tests/io/formats/test_format.py +++ b/pandas/tests/io/formats/test_format.py @@ -1328,10 +1328,16 @@ def test_to_string_float_formatting(self): '1 2.512000e-01') assert df_s == expected - df = DataFrame({'x': [0.19999, 100.0]}) - expected = ' x\n0 0.200\n1 100.000' + def test_to_string_float_format_no_fixed_width(self): + + df = DataFrame({'x': [0.19999]}) + # GH 21625 + expected = ' x\n0 0.200' assert df.to_string(float_format='%.3f') == expected - expected = ' x\n0 0\n1 100' + + # 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): From e554d07fefcecb75be62611ec6a55f1a4a932038 Mon Sep 17 00:00:00 2001 From: Tom Neep Date: Mon, 13 Aug 2018 16:53:03 +0200 Subject: [PATCH 3/7] Add whatsnew entry --- doc/source/whatsnew/v0.24.0.txt | 4 +++- pandas/tests/io/formats/test_format.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v0.24.0.txt b/doc/source/whatsnew/v0.24.0.txt index 2ddfba6d01a1b..268d8bc89b724 100644 --- a/doc/source/whatsnew/v0.24.0.txt +++ b/doc/source/whatsnew/v0.24.0.txt @@ -633,7 +633,9 @@ I/O - :func:`read_html()` no longer ignores all-whitespace ```` within ```` when considering the ``skiprows`` and ``header`` arguments. Previously, users had to decrease their ``header`` and ``skiprows`` values on such tables to work around the issue. (:issue:`21641`) - :func:`read_excel()` will correctly show the deprecation warning for previously deprecated ``sheetname`` (:issue:`17994`) -- +- :func:`DataFrame.to_string()`, :func:`DataFrame.to_html()` and + :func:`DataFrame.to_latex()` will correctly format output when a string is + passed as the ``float_format`` argument (:issue:`21625` and :issue:`22270`) Plotting ^^^^^^^^ diff --git a/pandas/tests/io/formats/test_format.py b/pandas/tests/io/formats/test_format.py index 4964ba15b6717..95cab993c96ee 100644 --- a/pandas/tests/io/formats/test_format.py +++ b/pandas/tests/io/formats/test_format.py @@ -1330,8 +1330,8 @@ def test_to_string_float_formatting(self): def test_to_string_float_format_no_fixed_width(self): - df = DataFrame({'x': [0.19999]}) # GH 21625 + df = DataFrame({'x': [0.19999]}) expected = ' x\n0 0.200' assert df.to_string(float_format='%.3f') == expected From 2069f3dbb30d86ee3c870b658d9d0e26cfb4a724 Mon Sep 17 00:00:00 2001 From: Tom Neep Date: Tue, 14 Aug 2018 10:03:42 +0200 Subject: [PATCH 4/7] Comma to and in whatsnew entry --- doc/source/whatsnew/v0.24.0.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v0.24.0.txt b/doc/source/whatsnew/v0.24.0.txt index 268d8bc89b724..70d90211ab6eb 100644 --- a/doc/source/whatsnew/v0.24.0.txt +++ b/doc/source/whatsnew/v0.24.0.txt @@ -635,7 +635,7 @@ I/O - :func:`read_excel()` will correctly show the deprecation warning for previously deprecated ``sheetname`` (:issue:`17994`) - :func:`DataFrame.to_string()`, :func:`DataFrame.to_html()` and :func:`DataFrame.to_latex()` will correctly format output when a string is - passed as the ``float_format`` argument (:issue:`21625` and :issue:`22270`) + passed as the ``float_format`` argument (:issue:`21625`, :issue:`22270`) Plotting ^^^^^^^^ From 5fa9ff8b3c757207cfed7a5f3291479b5989a7da Mon Sep 17 00:00:00 2001 From: Tom Neep Date: Fri, 23 Nov 2018 14:14:51 +0100 Subject: [PATCH 5/7] Modify whatsnew entry --- doc/source/whatsnew/v0.24.0.rst | 1 + 1 file changed, 1 insertion(+) 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 ^^^^^^^^ From bda9961e2bb49d4f26ae8152e0a96a117d1cfe2a Mon Sep 17 00:00:00 2001 From: Tom Neep Date: Sat, 24 Nov 2018 12:25:26 +0100 Subject: [PATCH 6/7] Adding tests to test_to_html and test_to_latex --- pandas/io/formats/format.py | 1 + .../formats/data/gh21625_expected_output.html | 14 ++++++++++ .../formats/data/gh22270_expected_output.html | 14 ++++++++++ pandas/tests/io/formats/test_to_html.py | 12 +++++++++ pandas/tests/io/formats/test_to_latex.py | 26 +++++++++++++++++++ 5 files changed, 67 insertions(+) create mode 100644 pandas/tests/io/formats/data/gh21625_expected_output.html create mode 100644 pandas/tests/io/formats/data/gh22270_expected_output.html diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index 16cd17cb85824..4c08ee89c33df 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -960,6 +960,7 @@ 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 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_to_html.py b/pandas/tests/io/formats/test_to_html.py index 0da48f60f1b51..bb8f06f3c5045 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 \ No newline at end of file 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 From a9666bd59a6e2b0ac9ca6ba0f620cb559f7a4e26 Mon Sep 17 00:00:00 2001 From: Tom Neep Date: Mon, 26 Nov 2018 13:26:47 +0100 Subject: [PATCH 7/7] Add new line to end of test_to_html.py --- pandas/tests/io/formats/test_to_html.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/io/formats/test_to_html.py b/pandas/tests/io/formats/test_to_html.py index bb8f06f3c5045..882a629b5b706 100644 --- a/pandas/tests/io/formats/test_to_html.py +++ b/pandas/tests/io/formats/test_to_html.py @@ -476,4 +476,4 @@ def test_to_html_float_format_no_fixed_width(self, datapath): # GH 22270 df = DataFrame({'x': [100.0]}) expected = expected_html(datapath, 'gh22270_expected_output') - assert df.to_html(float_format='%.0f') == expected \ No newline at end of file + assert df.to_html(float_format='%.0f') == expected