@@ -1506,14 +1506,16 @@ def format_values_with(float_format):
1506
1506
1507
1507
# default formatter leaves a space to the left when formatting
1508
1508
# floats, must be consistent for left-justifying NaNs (GH #25061)
1509
- if self .justify == "left" :
1510
- na_rep = " " + self .na_rep
1511
- else :
1512
- na_rep = self .na_rep
1509
+ na_rep = " " + self .na_rep if self .justify == "left" else self .na_rep
1513
1510
1514
- # separate the wheat from the chaff
1511
+ # different formatting strategies for complex and non-complex data
1512
+ # need to distinguish complex and float NaNs (GH #53762)
1515
1513
values = self .values
1516
1514
is_complex = is_complex_dtype (values )
1515
+ if is_complex :
1516
+ na_rep = f"{ na_rep } +{ 0 :.{self .digits }f} j"
1517
+
1518
+ # separate the wheat from the chaff
1517
1519
values = format_with_na_rep (values , formatter , na_rep )
1518
1520
1519
1521
if self .fixed_width :
@@ -1912,22 +1914,26 @@ def _trim_zeros_complex(str_complexes: np.ndarray, decimal: str = ".") -> list[s
1912
1914
Separates the real and imaginary parts from the complex number, and
1913
1915
executes the _trim_zeros_float method on each of those.
1914
1916
"""
1915
- trimmed = [
1916
- "" .join (_trim_zeros_float (re .split (r"([j+-])" , x ), decimal ))
1917
- for x in str_complexes
1918
- ]
1919
-
1920
- # pad strings to the length of the longest trimmed string for alignment
1921
- lengths = [len (s ) for s in trimmed ]
1922
- max_length = max (lengths )
1917
+ real_part , imag_part = [], []
1918
+ for x in str_complexes :
1919
+ # Complex numbers are represented as "(-)xxx(+/-)xxxj"
1920
+ # The split will give [maybe "-", "xxx", "+/-", "xxx", "j", ""]
1921
+ # Therefore, the imaginary part is the 4th and 3rd last elements,
1922
+ # and the real part is everything before the imaginary part
1923
+ trimmed = re .split (r"([j+-])" , x )
1924
+ real_part .append ("" .join (trimmed [:- 4 ]))
1925
+ imag_part .append ("" .join (trimmed [- 4 :- 2 ]))
1926
+
1927
+ # We want to align the lengths of the real and imaginary parts of each complex
1928
+ # number, as well as the lengths the real (resp. complex) parts of all numbers
1929
+ # in the array
1930
+ n = len (str_complexes )
1931
+ padded_parts = _trim_zeros_float (real_part + imag_part , decimal )
1923
1932
padded = [
1924
- s [: - ((k - 1 ) // 2 + 1 )] # real part
1925
- + (max_length - k ) // 2 * "0"
1926
- + s [- ((k - 1 ) // 2 + 1 ) : - ((k - 1 ) // 2 )] # + / -
1927
- + s [- ((k - 1 ) // 2 ) : - 1 ] # imaginary part
1928
- + (max_length - k ) // 2 * "0"
1929
- + s [- 1 ]
1930
- for s , k in zip (trimmed , lengths )
1933
+ padded_parts [i ] # real part (including - or space, possibly "NaN")
1934
+ + padded_parts [i + n ] # imaginary part (including + or -)
1935
+ + "j"
1936
+ for i in range (n )
1931
1937
]
1932
1938
return padded
1933
1939
0 commit comments