@@ -5890,32 +5890,36 @@ def _arith_method(self, other, op):
5890
5890
self , other = self ._align_for_op (other )
5891
5891
return base .IndexOpsMixin ._arith_method (self , other , op )
5892
5892
5893
- def _align_for_op (self , right , align_asobject : bool = False ):
5894
- """align lhs and rhs Series"""
5895
- # TODO: Different from DataFrame._align_for_op, list, tuple and ndarray
5896
- # are not coerced here
5897
- # because Series has inconsistencies described in GH#13637
5893
+ def _align_for_op (self , right , align_asobject = False , fill_value = np .nan ):
5894
+ """Align lhs and rhs Series for arithmetic operations"""
5895
+
5898
5896
left = self
5899
5897
5900
- if isinstance (right , Series ):
5901
- # avoid repeated alignment
5902
- if not left .index .equals (right .index ):
5903
- if align_asobject :
5904
- if left .dtype not in (object , np .bool_ ) or right .dtype not in (
5905
- object ,
5906
- np .bool_ ,
5907
- ):
5908
- pass
5909
- # GH#52538 no longer cast in these cases
5910
- else :
5911
- # to keep original value's dtype for bool ops
5912
- left = left .astype (object )
5913
- right = right .astype (object )
5914
-
5915
- left , right = left .align (right )
5916
-
5917
- return left , right
5898
+ if not isinstance (right , Series ):
5899
+ return left , right
5900
+
5901
+ if left .index .equals (right .index ):
5902
+ return left , right
5918
5903
5904
+ if not (hasattr (left .index , "levels" ) or hasattr (right .index , "levels" )):
5905
+ if align_asobject :
5906
+ if left .empty or right .empty :
5907
+ if left .dtype not in (object , np .bool_ ) or right .dtype not in (object , np .bool_ ):
5908
+ return left .iloc [0 :0 ], right .iloc [0 :0 ]
5909
+ return left .align (right , join = 'outer' , fill_value = fill_value )
5910
+
5911
+ if hasattr (left .index , "levels" ) and not hasattr (right .index , "levels" ):
5912
+ if left .empty or right .empty :
5913
+ return left .iloc [0 :0 ], right .iloc [0 :0 ]
5914
+ else :
5915
+ first_level = left .index .get_level_values (0 )
5916
+ left = left .astype (object )
5917
+ right = right .astype (object )
5918
+ right_aligned = right .reindex (first_level , fill_value = fill_value )
5919
+ return left , right_aligned
5920
+
5921
+ return left .align (right , join = 'outer' , fill_value = fill_value )
5922
+
5919
5923
def _binop (self , other : Series , func , level = None , fill_value = None ) -> Series :
5920
5924
"""
5921
5925
Perform generic binary operation with optional fill value.
0 commit comments