Skip to content

Backport PR #40850 on branch 1.2.x (REGR: object column repr not respecting float format) #40875

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/source/whatsnew/v1.2.4.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Fixed regressions
- Fixed regression in (in)equality comparison of ``pd.NaT`` with a non-datetimelike numpy array returning a scalar instead of an array (:issue:`40722`)
- Fixed regression in :meth:`DataFrame.where` not returning a copy in the case of an all True condition (:issue:`39595`)
- Fixed regression in :meth:`DataFrame.replace` raising ``IndexError`` when ``regex`` was a multi-key dictionary (:issue:`39338`)
-
- Fixed regression in repr of floats in an ``object`` column not respecting ``float_format`` when printed in the console or outputted through :meth:`DataFrame.to_string`, :meth:`DataFrame.to_html`, and :meth:`DataFrame.to_latex` (:issue:`40024`)

.. ---------------------------------------------------------------------------

Expand Down
6 changes: 4 additions & 2 deletions pandas/io/formats/format.py
Original file line number Diff line number Diff line change
Expand Up @@ -1254,7 +1254,9 @@ def _format_strings(self) -> List[str]:
float_format = get_option("display.float_format")
if float_format is None:
precision = get_option("display.precision")
float_format = lambda x: f"{x: .{precision:d}f}"
float_format = lambda x: _trim_zeros_single_float(
f"{x: .{precision:d}f}"
)
else:
float_format = self.float_format

Expand Down Expand Up @@ -1305,7 +1307,7 @@ def _format(x):
if not is_float_type[i] and leading_space:
fmt_values.append(f" {_format(v)}")
elif is_float_type[i]:
fmt_values.append(_trim_zeros_single_float(float_format(v)))
fmt_values.append(float_format(v))
else:
if leading_space is False:
# False specifically, so that the default is
Expand Down
15 changes: 15 additions & 0 deletions pandas/tests/io/formats/test_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -2021,6 +2021,21 @@ def test_repr_str_float_truncation(self, data, expected):
result = repr(series)
assert result == expected

@pytest.mark.parametrize(
"float_format,expected",
[
("{:,.0f}".format, "0 1,000\n1 test\ndtype: object"),
("{:.4f}".format, "0 1000.0000\n1 test\ndtype: object"),
],
)
def test_repr_float_format_in_object_col(self, float_format, expected):
# GH#40024
df = Series([1000.0, "test"])
with option_context("display.float_format", float_format):
result = repr(df)

assert result == expected

def test_dict_entries(self):
df = DataFrame({"A": [{"a": 1, "b": 2}]})

Expand Down
26 changes: 26 additions & 0 deletions pandas/tests/io/formats/test_to_html.py
Original file line number Diff line number Diff line change
Expand Up @@ -878,3 +878,29 @@ def test_to_html_na_rep_and_float_format(na_rep):
</tbody>
</table>"""
assert result == expected


def test_to_html_float_format_object_col():
# GH#40024
df = DataFrame(data={"x": [1000.0, "test"]})
result = df.to_html(float_format=lambda x: f"{x:,.0f}")
expected = """<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>x</th>
</tr>
</thead>
<tbody>
<tr>
<th>0</th>
<td>1,000</td>
</tr>
<tr>
<th>1</th>
<td>test</td>
</tr>
</tbody>
</table>"""

assert result == expected
18 changes: 18 additions & 0 deletions pandas/tests/io/formats/test_to_latex.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,24 @@ def test_to_latex_column_format(self):
)
assert result == expected

def test_to_latex_float_format_object_col(self):
# GH#40024
ser = Series([1000.0, "test"])
result = ser.to_latex(float_format="{:,.0f}".format)
expected = _dedent(
r"""
\begin{tabular}{ll}
\toprule
{} & 0 \\
\midrule
0 & 1,000 \\
1 & test \\
\bottomrule
\end{tabular}
"""
)
assert result == expected

def test_to_latex_empty_tabular(self):
df = DataFrame()
result = df.to_latex()
Expand Down