@@ -2592,47 +2592,6 @@ def _get_reconciled_name_object(self, other):
2592
2592
return self .rename (name )
2593
2593
return self
2594
2594
2595
- @final
2596
- def _union_incompatible_dtypes (self , other , sort ):
2597
- """
2598
- Casts this and other index to object dtype to allow the formation
2599
- of a union between incompatible types.
2600
-
2601
- Parameters
2602
- ----------
2603
- other : Index or array-like
2604
- sort : False or None, default False
2605
- Whether to sort the resulting index.
2606
-
2607
- * False : do not sort the result.
2608
- * None : sort the result, except when `self` and `other` are equal
2609
- or when the values cannot be compared.
2610
-
2611
- Returns
2612
- -------
2613
- Index
2614
- """
2615
- this = self .astype (object , copy = False )
2616
- # cast to Index for when `other` is list-like
2617
- other = Index (other ).astype (object , copy = False )
2618
- return Index .union (this , other , sort = sort ).astype (object , copy = False )
2619
-
2620
- def _can_union_without_object_cast (self , other ) -> bool :
2621
- """
2622
- Check whether this and the other dtype are compatible with each other.
2623
- Meaning a union can be formed between them without needing to be cast
2624
- to dtype object.
2625
-
2626
- Parameters
2627
- ----------
2628
- other : Index or array-like
2629
-
2630
- Returns
2631
- -------
2632
- bool
2633
- """
2634
- return type (self ) is type (other ) and is_dtype_equal (self .dtype , other .dtype )
2635
-
2636
2595
@final
2637
2596
def _validate_sort_keyword (self , sort ):
2638
2597
if sort not in [None , False ]:
@@ -2696,8 +2655,24 @@ def union(self, other, sort=None):
2696
2655
self ._assert_can_do_setop (other )
2697
2656
other , result_name = self ._convert_can_do_setop (other )
2698
2657
2699
- if not self ._can_union_without_object_cast (other ):
2700
- return self ._union_incompatible_dtypes (other , sort = sort )
2658
+ if not is_dtype_equal (self .dtype , other .dtype ):
2659
+ dtype = find_common_type ([self .dtype , other .dtype ])
2660
+ if self ._is_numeric_dtype and other ._is_numeric_dtype :
2661
+ # Right now, we treat union(int, float) a bit special.
2662
+ # See https://github.com/pandas-dev/pandas/issues/26778 for discussion
2663
+ # We may change union(int, float) to go to object.
2664
+ # float | [u]int -> float (the special case)
2665
+ # <T> | <T> -> T
2666
+ # <T> | <U> -> object
2667
+ if not (is_integer_dtype (self .dtype ) and is_integer_dtype (other .dtype )):
2668
+ dtype = "float64"
2669
+ else :
2670
+ # one is int64 other is uint64
2671
+ dtype = object
2672
+
2673
+ left = self .astype (dtype , copy = False )
2674
+ right = other .astype (dtype , copy = False )
2675
+ return left .union (right , sort = sort )
2701
2676
2702
2677
result = self ._union (other , sort = sort )
2703
2678
0 commit comments