Skip to content

Commit 2cd8632

Browse files
dsaxtonKevin D Smith
authored and
Kevin D Smith
committed
BUG/CLN: Clean float / complex string formatting (pandas-dev#36799)
1 parent e71dfb8 commit 2cd8632

File tree

4 files changed

+35
-14
lines changed

4 files changed

+35
-14
lines changed

doc/source/whatsnew/v1.2.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,7 @@ I/O
431431
- Bug in :func:`read_table` and :func:`read_csv` when ``delim_whitespace=True`` and ``sep=default`` (:issue:`36583`)
432432
- Bug in :meth:`to_json` with ``lines=True`` and ``orient='records'`` the last line of the record is not appended with 'new line character' (:issue:`36888`)
433433
- Bug in :meth:`read_parquet` with fixed offset timezones. String representation of timezones was not recognized (:issue:`35997`, :issue:`36004`)
434+
- Bug in output rendering of complex numbers showing too many trailing zeros (:issue:`36799`)
434435

435436
Plotting
436437
^^^^^^^^

pandas/core/frame.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -2661,11 +2661,11 @@ def memory_usage(self, index=True, deep=False) -> Series:
26612661
>>> df = pd.DataFrame(data)
26622662
>>> df.head()
26632663
int64 float64 complex128 object bool
2664-
0 1 1.0 1.000000+0.000000j 1 True
2665-
1 1 1.0 1.000000+0.000000j 1 True
2666-
2 1 1.0 1.000000+0.000000j 1 True
2667-
3 1 1.0 1.000000+0.000000j 1 True
2668-
4 1 1.0 1.000000+0.000000j 1 True
2664+
0 1 1.0 1.0+0.0j 1 True
2665+
1 1 1.0 1.0+0.0j 1 True
2666+
2 1 1.0 1.0+0.0j 1 True
2667+
3 1 1.0 1.0+0.0j 1 True
2668+
4 1 1.0 1.0+0.0j 1 True
26692669
26702670
>>> df.memory_usage()
26712671
Index 128

pandas/io/formats/format.py

+22-9
Original file line numberDiff line numberDiff line change
@@ -1474,9 +1474,9 @@ def format_values_with(float_format):
14741474

14751475
if self.fixed_width:
14761476
if is_complex:
1477-
result = _trim_zeros_complex(values, self.decimal, na_rep)
1477+
result = _trim_zeros_complex(values, self.decimal)
14781478
else:
1479-
result = _trim_zeros_float(values, self.decimal, na_rep)
1479+
result = _trim_zeros_float(values, self.decimal)
14801480
return np.asarray(result, dtype="object")
14811481

14821482
return values
@@ -1859,29 +1859,42 @@ def just(x: str) -> str:
18591859
return result
18601860

18611861

1862-
def _trim_zeros_complex(
1863-
str_complexes: np.ndarray, decimal: str = ".", na_rep: str = "NaN"
1864-
) -> List[str]:
1862+
def _trim_zeros_complex(str_complexes: np.ndarray, decimal: str = ".") -> List[str]:
18651863
"""
18661864
Separates the real and imaginary parts from the complex number, and
18671865
executes the _trim_zeros_float method on each of those.
18681866
"""
1869-
return [
1870-
"".join(_trim_zeros_float(re.split(r"([j+-])", x), decimal, na_rep))
1867+
trimmed = [
1868+
"".join(_trim_zeros_float(re.split(r"([j+-])", x), decimal))
18711869
for x in str_complexes
18721870
]
18731871

1872+
# pad strings to the length of the longest trimmed string for alignment
1873+
lengths = [len(s) for s in trimmed]
1874+
max_length = max(lengths)
1875+
padded = [
1876+
s[: -((k - 1) // 2 + 1)] # real part
1877+
+ (max_length - k) // 2 * "0"
1878+
+ s[-((k - 1) // 2 + 1) : -((k - 1) // 2)] # + / -
1879+
+ s[-((k - 1) // 2) : -1] # imaginary part
1880+
+ (max_length - k) // 2 * "0"
1881+
+ s[-1]
1882+
for s, k in zip(trimmed, lengths)
1883+
]
1884+
return padded
1885+
18741886

18751887
def _trim_zeros_float(
1876-
str_floats: Union[np.ndarray, List[str]], decimal: str = ".", na_rep: str = "NaN"
1888+
str_floats: Union[np.ndarray, List[str]], decimal: str = "."
18771889
) -> List[str]:
18781890
"""
18791891
Trims zeros, leaving just one before the decimal points if need be.
18801892
"""
18811893
trimmed = str_floats
1894+
number_regex = re.compile(fr"\s*[\+-]?[0-9]+(\{decimal}[0-9]*)?")
18821895

18831896
def _is_number(x):
1884-
return x != na_rep and not x.endswith("inf")
1897+
return re.match(number_regex, x) is not None
18851898

18861899
def _cond(values):
18871900
finite = [x for x in values if _is_number(x)]

pandas/tests/io/formats/test_format.py

+7
Original file line numberDiff line numberDiff line change
@@ -3432,3 +3432,10 @@ def test_format_remove_leading_space_dataframe(input_array, expected):
34323432
# GH: 24980
34333433
df = pd.DataFrame(input_array).to_string(index=False)
34343434
assert df == expected
3435+
3436+
3437+
def test_to_string_complex_number_trims_zeros():
3438+
s = pd.Series([1.000000 + 1.000000j, 1.0 + 1.0j, 1.05 + 1.0j])
3439+
result = s.to_string()
3440+
expected = "0 1.00+1.00j\n1 1.00+1.00j\n2 1.05+1.00j"
3441+
assert result == expected

0 commit comments

Comments
 (0)