Skip to content

Commit 0ebabaa

Browse files
glemaitrePingviinituutti
authored andcommitted
BUG: fix floating precision formatting in presence of inf (pandas-dev#24863)
1 parent 81c26bd commit 0ebabaa

File tree

3 files changed

+43
-5
lines changed

3 files changed

+43
-5
lines changed

doc/source/whatsnew/v0.24.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -1751,6 +1751,7 @@ I/O
17511751
- Bug in :meth:`DataFrame.to_stata`, :class:`pandas.io.stata.StataWriter` and :class:`pandas.io.stata.StataWriter117` where a exception would leave a partially written and invalid dta file (:issue:`23573`)
17521752
- Bug in :meth:`DataFrame.to_stata` and :class:`pandas.io.stata.StataWriter117` that produced invalid files when using strLs with non-ASCII characters (:issue:`23573`)
17531753
- Bug in :class:`HDFStore` that caused it to raise ``ValueError`` when reading a Dataframe in Python 3 from fixed format written in Python 2 (:issue:`24510`)
1754+
- Bug in :func:`DataFrame.to_string()` and more generally in the floating ``repr`` formatter. Zeros were not trimmed if ``inf`` was present in a columns while it was the case with NA values. Zeros are now trimmed as in the presence of NA (:issue:`24861`).
17541755

17551756
Plotting
17561757
^^^^^^^^

pandas/io/formats/format.py

+9-5
Original file line numberDiff line numberDiff line change
@@ -1414,16 +1414,20 @@ def _trim_zeros(str_floats, na_rep='NaN'):
14141414
"""
14151415
trimmed = str_floats
14161416

1417+
def _is_number(x):
1418+
return (x != na_rep and not x.endswith('inf'))
1419+
14171420
def _cond(values):
1418-
non_na = [x for x in values if x != na_rep]
1419-
return (len(non_na) > 0 and all(x.endswith('0') for x in non_na) and
1420-
not (any(('e' in x) or ('E' in x) for x in non_na)))
1421+
finite = [x for x in values if _is_number(x)]
1422+
return (len(finite) > 0 and all(x.endswith('0') for x in finite) and
1423+
not (any(('e' in x) or ('E' in x) for x in finite)))
14211424

14221425
while _cond(trimmed):
1423-
trimmed = [x[:-1] if x != na_rep else x for x in trimmed]
1426+
trimmed = [x[:-1] if _is_number(x) else x for x in trimmed]
14241427

14251428
# leave one 0 after the decimal points if need be.
1426-
return [x + "0" if x.endswith('.') and x != na_rep else x for x in trimmed]
1429+
return [x + "0" if x.endswith('.') and _is_number(x) else x
1430+
for x in trimmed]
14271431

14281432

14291433
def _has_names(index):

pandas/tests/io/formats/test_format.py

+33
Original file line numberDiff line numberDiff line change
@@ -1465,6 +1465,39 @@ def test_to_string_format_na(self):
14651465
'4 4.0 bar')
14661466
assert result == expected
14671467

1468+
def test_to_string_format_inf(self):
1469+
# Issue #24861
1470+
tm.reset_display_options()
1471+
df = DataFrame({
1472+
'A': [-np.inf, np.inf, -1, -2.1234, 3, 4],
1473+
'B': [-np.inf, np.inf, 'foo', 'foooo', 'fooooo', 'bar']
1474+
})
1475+
result = df.to_string()
1476+
1477+
expected = (' A B\n'
1478+
'0 -inf -inf\n'
1479+
'1 inf inf\n'
1480+
'2 -1.0000 foo\n'
1481+
'3 -2.1234 foooo\n'
1482+
'4 3.0000 fooooo\n'
1483+
'5 4.0000 bar')
1484+
assert result == expected
1485+
1486+
df = DataFrame({
1487+
'A': [-np.inf, np.inf, -1., -2., 3., 4.],
1488+
'B': [-np.inf, np.inf, 'foo', 'foooo', 'fooooo', 'bar']
1489+
})
1490+
result = df.to_string()
1491+
1492+
expected = (' A B\n'
1493+
'0 -inf -inf\n'
1494+
'1 inf inf\n'
1495+
'2 -1.0 foo\n'
1496+
'3 -2.0 foooo\n'
1497+
'4 3.0 fooooo\n'
1498+
'5 4.0 bar')
1499+
assert result == expected
1500+
14681501
def test_to_string_decimal(self):
14691502
# Issue #23614
14701503
df = DataFrame({'A': [6.0, 3.1, 2.2]})

0 commit comments

Comments
 (0)