Skip to content

Commit c2a96c6

Browse files
authored
BUG: Fix FloatingArray output formatting (#36800)
1 parent d936b00 commit c2a96c6

File tree

3 files changed

+46
-18
lines changed

3 files changed

+46
-18
lines changed

pandas/core/frame.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -2656,7 +2656,7 @@ def memory_usage(self, index=True, deep=False) -> Series:
26562656
Examples
26572657
--------
26582658
>>> dtypes = ['int64', 'float64', 'complex128', 'object', 'bool']
2659-
>>> data = dict([(t, np.ones(shape=5000).astype(t))
2659+
>>> data = dict([(t, np.ones(shape=5000, dtype=int).astype(t))
26602660
... for t in dtypes])
26612661
>>> df = pd.DataFrame(data)
26622662
>>> df.head()
@@ -2691,7 +2691,7 @@ def memory_usage(self, index=True, deep=False) -> Series:
26912691
int64 40000
26922692
float64 40000
26932693
complex128 80000
2694-
object 160000
2694+
object 180000
26952695
bool 5000
26962696
dtype: int64
26972697
@@ -2790,7 +2790,7 @@ def transpose(self, *args, copy: bool = False) -> DataFrame:
27902790
>>> df2_transposed
27912791
0 1
27922792
name Alice Bob
2793-
score 9.5 8
2793+
score 9.5 8.0
27942794
employed False True
27952795
kids 0 0
27962796

pandas/io/formats/format.py

+21-15
Original file line numberDiff line numberDiff line change
@@ -1311,7 +1311,7 @@ def _format_strings(self) -> List[str]:
13111311
float_format = get_option("display.float_format")
13121312
if float_format is None:
13131313
precision = get_option("display.precision")
1314-
float_format = lambda x: f"{x: .{precision:d}g}"
1314+
float_format = lambda x: f"{x: .{precision:d}f}"
13151315
else:
13161316
float_format = self.float_format
13171317

@@ -1372,6 +1372,8 @@ def _format(x):
13721372
tpl = " {v}"
13731373
fmt_values.append(tpl.format(v=_format(v)))
13741374

1375+
fmt_values = _trim_zeros_float(str_floats=fmt_values, decimal=".")
1376+
13751377
return fmt_values
13761378

13771379

@@ -1891,27 +1893,31 @@ def _trim_zeros_float(
18911893
Trims zeros, leaving just one before the decimal points if need be.
18921894
"""
18931895
trimmed = str_floats
1894-
number_regex = re.compile(fr"\s*[\+-]?[0-9]+(\{decimal}[0-9]*)?")
1896+
number_regex = re.compile(fr"^\s*[\+-]?[0-9]+\{decimal}[0-9]*$")
18951897

1896-
def _is_number(x):
1898+
def is_number_with_decimal(x):
18971899
return re.match(number_regex, x) is not None
18981900

1899-
def _cond(values):
1900-
finite = [x for x in values if _is_number(x)]
1901-
has_decimal = [decimal in x for x in finite]
1901+
def should_trim(values: Union[np.ndarray, List[str]]) -> bool:
1902+
"""
1903+
Determine if an array of strings should be trimmed.
19021904
1903-
return (
1904-
len(finite) > 0
1905-
and all(has_decimal)
1906-
and all(x.endswith("0") for x in finite)
1907-
and not (any(("e" in x) or ("E" in x) for x in finite))
1908-
)
1905+
Returns True if all numbers containing decimals (defined by the
1906+
above regular expression) within the array end in a zero, otherwise
1907+
returns False.
1908+
"""
1909+
numbers = [x for x in values if is_number_with_decimal(x)]
1910+
return len(numbers) > 0 and all(x.endswith("0") for x in numbers)
19091911

1910-
while _cond(trimmed):
1911-
trimmed = [x[:-1] if _is_number(x) else x for x in trimmed]
1912+
while should_trim(trimmed):
1913+
trimmed = [x[:-1] if is_number_with_decimal(x) else x for x in trimmed]
19121914

19131915
# leave one 0 after the decimal points if need be.
1914-
return [x + "0" if x.endswith(decimal) and _is_number(x) else x for x in trimmed]
1916+
result = [
1917+
x + "0" if is_number_with_decimal(x) and x.endswith(decimal) else x
1918+
for x in trimmed
1919+
]
1920+
return result
19151921

19161922

19171923
def _has_names(index: Index) -> bool:

pandas/tests/io/formats/test_format.py

+22
Original file line numberDiff line numberDiff line change
@@ -3439,3 +3439,25 @@ def test_to_string_complex_number_trims_zeros():
34393439
result = s.to_string()
34403440
expected = "0 1.00+1.00j\n1 1.00+1.00j\n2 1.05+1.00j"
34413441
assert result == expected
3442+
3443+
3444+
def test_nullable_float_to_string(float_ea_dtype):
3445+
# https://github.com/pandas-dev/pandas/issues/36775
3446+
dtype = float_ea_dtype
3447+
s = pd.Series([0.0, 1.0, None], dtype=dtype)
3448+
result = s.to_string()
3449+
expected = """0 0.0
3450+
1 1.0
3451+
2 <NA>"""
3452+
assert result == expected
3453+
3454+
3455+
def test_nullable_int_to_string(any_nullable_int_dtype):
3456+
# https://github.com/pandas-dev/pandas/issues/36775
3457+
dtype = any_nullable_int_dtype
3458+
s = pd.Series([0, 1, None], dtype=dtype)
3459+
result = s.to_string()
3460+
expected = """0 0
3461+
1 1
3462+
2 <NA>"""
3463+
assert result == expected

0 commit comments

Comments
 (0)