diff --git a/doc/source/whatsnew/v1.2.0.rst b/doc/source/whatsnew/v1.2.0.rst index 2b4b10c39602a..2805bd9ac2db3 100644 --- a/doc/source/whatsnew/v1.2.0.rst +++ b/doc/source/whatsnew/v1.2.0.rst @@ -424,6 +424,7 @@ I/O - Bug in :func:`read_table` and :func:`read_csv` when ``delim_whitespace=True`` and ``sep=default`` (:issue:`36583`) - 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`) - Bug in :meth:`read_parquet` with fixed offset timezones. String representation of timezones was not recognized (:issue:`35997`, :issue:`36004`) +- Bug in output rendering of complex numbers showing too many trailing zeros (:issue:`36799`) Plotting ^^^^^^^^ diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 0314bdc4ee8ed..f8b8a2c6b6d10 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -2659,11 +2659,11 @@ def memory_usage(self, index=True, deep=False) -> Series: >>> df = pd.DataFrame(data) >>> df.head() int64 float64 complex128 object bool - 0 1 1.0 1.000000+0.000000j 1 True - 1 1 1.0 1.000000+0.000000j 1 True - 2 1 1.0 1.000000+0.000000j 1 True - 3 1 1.0 1.000000+0.000000j 1 True - 4 1 1.0 1.000000+0.000000j 1 True + 0 1 1.0 1.0+0.0j 1 True + 1 1 1.0 1.0+0.0j 1 True + 2 1 1.0 1.0+0.0j 1 True + 3 1 1.0 1.0+0.0j 1 True + 4 1 1.0 1.0+0.0j 1 True >>> df.memory_usage() Index 128 diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index 3e4780ec21378..f5908cf7ca7bb 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -1474,9 +1474,9 @@ def format_values_with(float_format): if self.fixed_width: if is_complex: - result = _trim_zeros_complex(values, self.decimal, na_rep) + result = _trim_zeros_complex(values, self.decimal) else: - result = _trim_zeros_float(values, self.decimal, na_rep) + result = _trim_zeros_float(values, self.decimal) return np.asarray(result, dtype="object") return values @@ -1857,29 +1857,42 @@ def just(x): return result -def _trim_zeros_complex( - str_complexes: np.ndarray, decimal: str = ".", na_rep: str = "NaN" -) -> List[str]: +def _trim_zeros_complex(str_complexes: np.ndarray, decimal: str = ".") -> List[str]: """ Separates the real and imaginary parts from the complex number, and executes the _trim_zeros_float method on each of those. """ - return [ - "".join(_trim_zeros_float(re.split(r"([j+-])", x), decimal, na_rep)) + trimmed = [ + "".join(_trim_zeros_float(re.split(r"([j+-])", x), decimal)) for x in str_complexes ] + # pad strings to the length of the longest trimmed string for alignment + lengths = [len(s) for s in trimmed] + max_length = max(lengths) + padded = [ + s[: -((k - 1) // 2 + 1)] # real part + + (max_length - k) // 2 * "0" + + s[-((k - 1) // 2 + 1) : -((k - 1) // 2)] # + / - + + s[-((k - 1) // 2) : -1] # imaginary part + + (max_length - k) // 2 * "0" + + s[-1] + for s, k in zip(trimmed, lengths) + ] + return padded + def _trim_zeros_float( - str_floats: Union[np.ndarray, List[str]], decimal: str = ".", na_rep: str = "NaN" + str_floats: Union[np.ndarray, List[str]], decimal: str = "." ) -> List[str]: """ Trims zeros, leaving just one before the decimal points if need be. """ trimmed = str_floats + number_regex = re.compile(fr"\s*[\+-]?[0-9]+(\{decimal}[0-9]*)?") def _is_number(x): - return x != na_rep and not x.endswith("inf") + return re.match(number_regex, x) is not None def _cond(values): finite = [x for x in values if _is_number(x)] diff --git a/pandas/tests/io/formats/test_format.py b/pandas/tests/io/formats/test_format.py index 68f5386fff7be..b30ceed23b02e 100644 --- a/pandas/tests/io/formats/test_format.py +++ b/pandas/tests/io/formats/test_format.py @@ -3432,3 +3432,10 @@ def test_format_remove_leading_space_dataframe(input_array, expected): # GH: 24980 df = pd.DataFrame(input_array).to_string(index=False) assert df == expected + + +def test_to_string_complex_number_trims_zeros(): + s = pd.Series([1.000000 + 1.000000j, 1.0 + 1.0j, 1.05 + 1.0j]) + result = s.to_string() + expected = "0 1.00+1.00j\n1 1.00+1.00j\n2 1.05+1.00j" + assert result == expected