@@ -4906,16 +4906,31 @@ def get_indexer_non_unique(self, target):
4906
4906
# Treat boolean labels passed to a numeric index as not found. Without
4907
4907
# this fix False and True would be treated as 0 and 1 respectively.
4908
4908
# (GH #16877)
4909
- no_matches = - 1 * np .ones (self .shape , dtype = np .intp )
4910
- return no_matches , no_matches
4909
+ return self ._get_indexer_non_comparable (target , method = None , unique = False )
4911
4910
4912
4911
pself , ptarget = self ._maybe_promote (target )
4913
4912
if pself is not self or ptarget is not target :
4914
4913
return pself .get_indexer_non_unique (ptarget )
4915
4914
4916
- if not self ._is_comparable_dtype (target .dtype ):
4917
- no_matches = - 1 * np .ones (self .shape , dtype = np .intp )
4918
- return no_matches , no_matches
4915
+ if not self ._should_compare (target ):
4916
+ return self ._get_indexer_non_comparable (target , method = None , unique = False )
4917
+
4918
+ if not is_dtype_equal (self .dtype , target .dtype ):
4919
+ # TODO: if object, could use infer_dtype to pre-empt costly
4920
+ # conversion if still non-comparable?
4921
+ dtype = find_common_type ([self .dtype , target .dtype ])
4922
+ if (
4923
+ dtype .kind in ["i" , "u" ]
4924
+ and is_categorical_dtype (target .dtype )
4925
+ and target .hasnans
4926
+ ):
4927
+ # FIXME: find_common_type incorrect with Categorical GH#38240
4928
+ # FIXME: some cases where float64 cast can be lossy?
4929
+ dtype = np .dtype (np .float64 )
4930
+
4931
+ this = self .astype (dtype , copy = False )
4932
+ that = target .astype (dtype , copy = False )
4933
+ return this .get_indexer_non_unique (that )
4919
4934
4920
4935
if is_categorical_dtype (target .dtype ):
4921
4936
tgt_values = np .asarray (target )
@@ -4968,7 +4983,7 @@ def _get_indexer_non_comparable(self, target: "Index", method, unique: bool = Tr
4968
4983
If doing an inequality check, i.e. method is not None.
4969
4984
"""
4970
4985
if method is not None :
4971
- other = _unpack_nested_dtype (target )
4986
+ other = unpack_nested_dtype (target )
4972
4987
raise TypeError (f"Cannot compare dtypes { self .dtype } and { other .dtype } " )
4973
4988
4974
4989
no_matches = - 1 * np .ones (target .shape , dtype = np .intp )
@@ -5019,7 +5034,7 @@ def _should_compare(self, other: "Index") -> bool:
5019
5034
"""
5020
5035
Check if `self == other` can ever have non-False entries.
5021
5036
"""
5022
- other = _unpack_nested_dtype (other )
5037
+ other = unpack_nested_dtype (other )
5023
5038
dtype = other .dtype
5024
5039
return self ._is_comparable_dtype (dtype ) or is_object_dtype (dtype )
5025
5040
@@ -6172,7 +6187,7 @@ def get_unanimous_names(*indexes: Index) -> Tuple[Label, ...]:
6172
6187
return names
6173
6188
6174
6189
6175
- def _unpack_nested_dtype (other : Index ) -> Index :
6190
+ def unpack_nested_dtype (other : Index ) -> Index :
6176
6191
"""
6177
6192
When checking if our dtype is comparable with another, we need
6178
6193
to unpack CategoricalDtype to look at its categories.dtype.
0 commit comments