@@ -4906,16 +4906,31 @@ def get_indexer_non_unique(self, target):
49064906 # Treat boolean labels passed to a numeric index as not found. Without
49074907 # this fix False and True would be treated as 0 and 1 respectively.
49084908 # (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 )
49114910
49124911 pself , ptarget = self ._maybe_promote (target )
49134912 if pself is not self or ptarget is not target :
49144913 return pself .get_indexer_non_unique (ptarget )
49154914
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 )
49194934
49204935 if is_categorical_dtype (target .dtype ):
49214936 tgt_values = np .asarray (target )
@@ -4968,7 +4983,7 @@ def _get_indexer_non_comparable(self, target: "Index", method, unique: bool = Tr
49684983 If doing an inequality check, i.e. method is not None.
49694984 """
49704985 if method is not None :
4971- other = _unpack_nested_dtype (target )
4986+ other = unpack_nested_dtype (target )
49724987 raise TypeError (f"Cannot compare dtypes { self .dtype } and { other .dtype } " )
49734988
49744989 no_matches = - 1 * np .ones (target .shape , dtype = np .intp )
@@ -5019,7 +5034,7 @@ def _should_compare(self, other: "Index") -> bool:
50195034 """
50205035 Check if `self == other` can ever have non-False entries.
50215036 """
5022- other = _unpack_nested_dtype (other )
5037+ other = unpack_nested_dtype (other )
50235038 dtype = other .dtype
50245039 return self ._is_comparable_dtype (dtype ) or is_object_dtype (dtype )
50255040
@@ -6172,7 +6187,7 @@ def get_unanimous_names(*indexes: Index) -> Tuple[Label, ...]:
61726187 return names
61736188
61746189
6175- def _unpack_nested_dtype (other : Index ) -> Index :
6190+ def unpack_nested_dtype (other : Index ) -> Index :
61766191 """
61776192 When checking if our dtype is comparable with another, we need
61786193 to unpack CategoricalDtype to look at its categories.dtype.
0 commit comments