13
13
from pandas ._libs .tslibs import OutOfBoundsDatetime , Timestamp
14
14
from pandas ._libs .tslibs .period import IncompatibleFrequency
15
15
from pandas ._libs .tslibs .timezones import tz_compare
16
- from pandas ._typing import Label
16
+ from pandas ._typing import DtypeObj , Label
17
17
from pandas .compat import set_function_name
18
18
from pandas .compat .numpy import function as nv
19
19
from pandas .util ._decorators import Appender , Substitution , cache_readonly , doc
@@ -4626,6 +4626,10 @@ def get_indexer_non_unique(self, target):
4626
4626
if pself is not self or ptarget is not target :
4627
4627
return pself .get_indexer_non_unique (ptarget )
4628
4628
4629
+ if not self ._is_comparable_dtype (target .dtype ):
4630
+ no_matches = - 1 * np .ones (self .shape , dtype = np .intp )
4631
+ return no_matches , no_matches
4632
+
4629
4633
if is_categorical_dtype (target .dtype ):
4630
4634
tgt_values = np .asarray (target )
4631
4635
else :
@@ -4651,16 +4655,33 @@ def get_indexer_for(self, target, **kwargs):
4651
4655
indexer , _ = self .get_indexer_non_unique (target , ** kwargs )
4652
4656
return indexer
4653
4657
4654
- def _maybe_promote (self , other ):
4655
- # A hack, but it works
4658
+ def _maybe_promote (self , other : "Index" ):
4659
+ """
4660
+ When dealing with an object-dtype Index and a non-object Index, see
4661
+ if we can upcast the object-dtype one to improve performance.
4662
+ """
4656
4663
4657
4664
if self .inferred_type == "date" and isinstance (other , ABCDatetimeIndex ):
4658
4665
return type (other )(self ), other
4666
+ elif self .inferred_type == "timedelta" and isinstance (other , ABCTimedeltaIndex ):
4667
+ # TODO: we dont have tests that get here
4668
+ return type (other )(self ), other
4659
4669
elif self .inferred_type == "boolean" :
4660
4670
if not is_object_dtype (self .dtype ):
4661
4671
return self .astype ("object" ), other .astype ("object" )
4672
+
4673
+ if not is_object_dtype (self .dtype ) and is_object_dtype (other .dtype ):
4674
+ # Reverse op so we dont need to re-implement on the subclasses
4675
+ other , self = other ._maybe_promote (self )
4676
+
4662
4677
return self , other
4663
4678
4679
+ def _is_comparable_dtype (self , dtype : DtypeObj ) -> bool :
4680
+ """
4681
+ Can we compare values of the given dtype to our own?
4682
+ """
4683
+ return True
4684
+
4664
4685
def groupby (self , values ) -> PrettyDict [Hashable , np .ndarray ]:
4665
4686
"""
4666
4687
Group the index labels by a given array of values.
0 commit comments