@@ -3254,12 +3254,47 @@ def symmetric_difference(self, other, result_name=None, sort=None):
32543254 if result_name is None :
32553255 result_name = result_name_update
32563256
3257- left = self .difference (other , sort = False )
3258- right = other .difference (self , sort = False )
3259- result = left .union (right , sort = sort )
3257+ if not self ._should_compare (other ):
3258+ return self .union (other , sort = sort ).rename (result_name )
3259+
3260+ elif not is_dtype_equal (self .dtype , other .dtype ):
3261+ dtype = self ._find_common_type_compat (other )
3262+ this = self .astype (dtype , copy = False )
3263+ that = other .astype (dtype , copy = False )
3264+ return this .symmetric_difference (that , sort = sort ).rename (result_name )
3265+
3266+ this = self .unique ()
3267+ other = other .unique ()
3268+ indexer = this .get_indexer_for (other )
3269+
3270+ # {this} minus {other}
3271+ common_indexer = indexer .take ((indexer != - 1 ).nonzero ()[0 ])
3272+ left_indexer = np .setdiff1d (
3273+ np .arange (this .size ), common_indexer , assume_unique = True
3274+ )
3275+ left_diff = this ._values .take (left_indexer )
3276+
3277+ # {other} minus {this}
3278+ right_indexer = (indexer == - 1 ).nonzero ()[0 ]
3279+ right_diff = other ._values .take (right_indexer )
3280+
3281+ res_values = concat_compat ([left_diff , right_diff ])
3282+ res_values = _maybe_try_sort (res_values , sort )
3283+
3284+ result = Index (res_values , name = result_name )
3285+
3286+ if self ._is_multi :
3287+ self = cast ("MultiIndex" , self )
3288+ if len (result ) == 0 :
3289+ # On equal symmetric_difference MultiIndexes the difference is empty.
3290+ # Therefore, an empty MultiIndex is returned GH#13490
3291+ return type (self )(
3292+ levels = [[] for _ in range (self .nlevels )],
3293+ codes = [[] for _ in range (self .nlevels )],
3294+ names = result .name ,
3295+ )
3296+ return type (self ).from_tuples (result , names = result .name )
32603297
3261- if result_name is not None :
3262- result = result .rename (result_name )
32633298 return result
32643299
32653300 @final
0 commit comments