Skip to content

Fix string formatting #52883

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

Closed
wants to merge 14 commits into from
1 change: 1 addition & 0 deletions doc/source/whatsnew/v2.0.1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Bug fixes
- Bug in logical and comparison operations between :class:`ArrowDtype` and numpy masked types (e.g. ``"boolean"``) (:issue:`52625`)
- Fixed bug in :func:`merge` when merging with ``ArrowDtype`` one one and a NumPy dtype on the other side (:issue:`52406`)
- Fixed segfault in :meth:`Series.to_numpy` with ``null[pyarrow]`` dtype (:issue:`52443`)
- Bug in DataFrame.to_string() creates extra space for string dtypes in pandas >=2.0 (:issue:`52690`)

.. ---------------------------------------------------------------------------
.. _whatsnew_201.other:
Expand Down
5 changes: 4 additions & 1 deletion pandas/io/formats/format.py
Original file line number Diff line number Diff line change
Expand Up @@ -1424,7 +1424,10 @@ def _format(x):
fmt_values = []
for i, v in enumerate(vals):
if not is_float_type[i] and leading_space or self.formatter is not None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if not is_float_type[i] and leading_space or self.formatter is not None:
if (not is_float_type[i] or self.formatter is not None) and leading_space:
fmt_values.append(f" {_format(v)}")

fmt_values.append(f" {_format(v)}")
if leading_space:
fmt_values.append(f" {_format(v)}")
else:
fmt_values.append(f"{_format(v)}")
Comment on lines +1395 to +1398
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if leading_space:
fmt_values.append(f" {_format(v)}")
else:
fmt_values.append(f"{_format(v)}")

It seems this if/else is already handled by the else block below. I think a smaller change is sufficient. WDYT? @reddyrg1 @mroeschke @phofl

elif is_float_type[i]:
fmt_values.append(float_format(v))
else:
Expand Down
17 changes: 17 additions & 0 deletions pandas/tests/io/formats/test_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -2099,6 +2099,23 @@ def test_max_rows_fitted(self, length, min_rows, max_rows, expected):
result = formatter.max_rows_fitted
assert result == expected

def test_no_extra_space(self):
"""Check that no extra space is given

GH #52690

"""
# Expected Output
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you remove these comments?

col1 = "TEST"
col2 = "PANDAS"
col3 = "to_string"
expected = f"{col1:<6s} {col2:<7s} {col3:<10s}"
# Testing
df = DataFrame([{"col1": "TEST", "col2": "PANDAS", "col3": "to_string"}])
d = {"col1": "{:<6s}".format, "col2": "{:<7s}".format, "col3": "{:<10s}".format}
result = df.to_string(index=False, header=False, formatters=d)
assert result == expected


def gen_series_formatting():
s1 = Series(["a"] * 100)
Expand Down