@@ -3209,7 +3209,6 @@ def _wrap_difference_result(self, other, result):
3209
3209
# We will override for MultiIndex to handle empty results
3210
3210
return self ._wrap_setop_result (other , result )
3211
3211
3212
- @final
3213
3212
def symmetric_difference (self , other , result_name = None , sort = None ):
3214
3213
"""
3215
3214
Compute the symmetric difference of two Index objects.
@@ -3251,21 +3250,46 @@ def symmetric_difference(self, other, result_name=None, sort=None):
3251
3250
if result_name is None :
3252
3251
result_name = result_name_update
3253
3252
3254
- left = self .difference (other , sort = False )
3255
- right = other .difference (self , sort = False )
3256
- result = left .union (right , sort = sort )
3253
+ if not self ._should_compare (other ):
3254
+ return self .union (other , sort = sort ).rename (result_name )
3257
3255
3258
- if result_name is not None :
3259
- result = result .rename (result_name )
3256
+ elif not is_dtype_equal (self .dtype , other .dtype ):
3257
+ dtype = self ._find_common_type_compat (other )
3258
+ this = self .astype (dtype , copy = False )
3259
+ that = other .astype (dtype , copy = False )
3260
+ return this .symmetric_difference (that , sort = sort ).rename (result_name )
3260
3261
3261
- if self ._is_multi and len (result ) == 0 :
3262
- # On equal symmetric_difference MultiIndexes the difference is empty.
3263
- # Therefore, an empty MultiIndex is returned GH#13490
3264
- return type (self )(
3265
- levels = [[] for _ in range (self .nlevels )],
3266
- codes = [[] for _ in range (self .nlevels )],
3267
- names = result .names ,
3268
- )
3262
+ this = self .unique ()
3263
+ other = other .unique ()
3264
+ indexer = this .get_indexer_for (other )
3265
+
3266
+ # {this} minus {other}
3267
+ common_indexer = indexer .take ((indexer != - 1 ).nonzero ()[0 ])
3268
+ left_indexer = np .setdiff1d (
3269
+ np .arange (this .size ), common_indexer , assume_unique = True
3270
+ )
3271
+ left_diff = this ._values .take (left_indexer )
3272
+
3273
+ # {other} minus {this}
3274
+ right_indexer = (indexer == - 1 ).nonzero ()[0 ]
3275
+ right_diff = other ._values .take (right_indexer )
3276
+
3277
+ res_values = concat_compat ([left_diff , right_diff ])
3278
+ res_values = _maybe_try_sort (res_values , sort )
3279
+
3280
+ result = Index (res_values , name = result_name )
3281
+
3282
+ if self ._is_multi :
3283
+ self = cast ("MultiIndex" , self )
3284
+ if len (result ) == 0 :
3285
+ # On equal symmetric_difference MultiIndexes the difference is empty.
3286
+ # Therefore, an empty MultiIndex is returned GH#13490
3287
+ return type (self )(
3288
+ levels = [[] for _ in range (self .nlevels )],
3289
+ codes = [[] for _ in range (self .nlevels )],
3290
+ names = result .name ,
3291
+ )
3292
+ return type (self ).from_tuples (result , names = result .name )
3269
3293
3270
3294
return result
3271
3295
0 commit comments