@@ -1492,6 +1492,35 @@ def format_with_na_rep(values: ArrayLike, formatter: Callable, na_rep: str):
14921492 ).reshape (values .shape )
14931493 return formatted
14941494
1495+ def format_complex_with_na_rep (
1496+ values : ArrayLike , formatter : Callable , na_rep : str
1497+ ):
1498+ real_values = np .real (values ).ravel () # type: ignore[arg-type]
1499+ imag_values = np .imag (values ).ravel () # type: ignore[arg-type]
1500+ real_mask , imag_mask = isna (real_values ), isna (imag_values )
1501+ formatted_lst = []
1502+ for val , real_val , imag_val , re_isna , im_isna in zip (
1503+ values .ravel (),
1504+ real_values ,
1505+ imag_values ,
1506+ real_mask ,
1507+ imag_mask ,
1508+ ):
1509+ if not re_isna and not im_isna :
1510+ formatted_lst .append (formatter (val ))
1511+ elif not re_isna : # xxx+nanj
1512+ formatted_lst .append (f"{ formatter (real_val )} +{ na_rep } j" )
1513+ elif not im_isna : # nan[+/-]xxxj
1514+ # The imaginary part may either start with a "-" or a space
1515+ imag_formatted = formatter (imag_val ).strip ()
1516+ if imag_formatted .startswith ("-" ):
1517+ formatted_lst .append (f"{ na_rep } { imag_formatted } j" )
1518+ else :
1519+ formatted_lst .append (f"{ na_rep } +{ imag_formatted } j" )
1520+ else : # nan+nanj
1521+ formatted_lst .append (f"{ na_rep } +{ na_rep } j" )
1522+ return np .array (formatted_lst ).reshape (values .shape )
1523+
14951524 if self .formatter is not None :
14961525 return format_with_na_rep (self .values , self .formatter , self .na_rep )
14971526
@@ -1512,11 +1541,12 @@ def format_values_with(float_format):
15121541 # need to distinguish complex and float NaNs (GH #53762)
15131542 values = self .values
15141543 is_complex = is_complex_dtype (values )
1515- if is_complex :
1516- na_rep = f"{ na_rep } +{ 0 :.{self .digits }f} j"
15171544
15181545 # separate the wheat from the chaff
1519- values = format_with_na_rep (values , formatter , na_rep )
1546+ if is_complex :
1547+ values = format_complex_with_na_rep (values , formatter , na_rep )
1548+ else :
1549+ values = format_with_na_rep (values , formatter , na_rep )
15201550
15211551 if self .fixed_width :
15221552 if is_complex :
@@ -1917,7 +1947,7 @@ def _trim_zeros_complex(str_complexes: np.ndarray, decimal: str = ".") -> list[s
19171947 real_part , imag_part = [], []
19181948 for x in str_complexes :
19191949 # Complex numbers are represented as "(-)xxx(+/-)xxxj"
1920- # The split will give [maybe "-", "xxx", "+/-", "xxx", "j", ""]
1950+ # The split will give [{"", "-"} , "xxx", "+/-", "xxx", "j", ""]
19211951 # Therefore, the imaginary part is the 4th and 3rd last elements,
19221952 # and the real part is everything before the imaginary part
19231953 trimmed = re .split (r"([j+-])" , x )
@@ -1929,11 +1959,13 @@ def _trim_zeros_complex(str_complexes: np.ndarray, decimal: str = ".") -> list[s
19291959 # in the array
19301960 n = len (str_complexes )
19311961 padded_parts = _trim_zeros_float (real_part + imag_part , decimal )
1962+ padded_length = max (len (part ) for part in padded_parts ) - 1
19321963 padded = [
1933- padded_parts [i ] # real part (including - or space, possibly "NaN")
1934- + padded_parts [i + n ] # imaginary part (including + or -)
1964+ real_pt # real part, possibly NaN
1965+ + imag_pt [0 ] # +/-
1966+ + f"{ imag_pt [1 :]:>{padded_length }} " # complex part (no sign), possibly nan
19351967 + "j"
1936- for i in range ( n )
1968+ for real_pt , imag_pt in zip ( padded_parts [: n ], padded_parts [ n :] )
19371969 ]
19381970 return padded
19391971
0 commit comments