@@ -87,11 +87,7 @@ cdef class IndexEngine:
87
87
values = self .values
88
88
89
89
self ._check_type(val)
90
- try :
91
- loc = _bin_search(values, val) # .searchsorted(val, side='left')
92
- except TypeError :
93
- # GH#35788 e.g. val=None with float64 values
94
- raise KeyError (val)
90
+ loc = self ._searchsorted_left(val)
95
91
if loc >= len (values):
96
92
raise KeyError (val)
97
93
if values[loc] != val:
@@ -110,6 +106,17 @@ cdef class IndexEngine:
110
106
# GH#41775 OverflowError e.g. if we are uint64 and val is -1
111
107
raise KeyError (val)
112
108
109
+ cdef Py_ssize_t _searchsorted_left(self , val) except ? - 1 :
110
+ """
111
+ See ObjectEngine._searchsorted_left.__doc__.
112
+ """
113
+ try :
114
+ loc = self .values.searchsorted(val, side = " left" )
115
+ except TypeError as err:
116
+ # GH#35788 e.g. val=None with float64 values
117
+ raise KeyError (val)
118
+ return loc
119
+
113
120
cdef inline _get_loc_duplicates(self , object val):
114
121
# -> Py_ssize_t | slice | ndarray[bool]
115
122
cdef:
@@ -373,6 +380,11 @@ cdef class IndexEngine:
373
380
374
381
375
382
cdef Py_ssize_t _bin_search(ndarray values, object val) except - 1 :
383
+ # GH#1757 ndarray.searchsorted is not safe to use with array of tuples
384
+ # (treats a tuple `val` as a sequence of keys instead of a single key),
385
+ # so we implement something similar.
386
+ # This is equivalent to the stdlib's bisect.bisect_left
387
+
376
388
cdef:
377
389
Py_ssize_t mid = 0 , lo = 0 , hi = len (values) - 1
378
390
object pval
@@ -405,6 +417,15 @@ cdef class ObjectEngine(IndexEngine):
405
417
cdef _make_hash_table(self , Py_ssize_t n):
406
418
return _hash.PyObjectHashTable(n)
407
419
420
+ cdef Py_ssize_t _searchsorted_left(self , val) except ? - 1 :
421
+ # using values.searchsorted here would treat a tuple `val` as a sequence
422
+ # instead of a single key, so we use a different implementation
423
+ try :
424
+ loc = _bin_search(self .values, val)
425
+ except TypeError as err:
426
+ raise KeyError (val) from err
427
+ return loc
428
+
408
429
409
430
cdef class DatetimeEngine(Int64Engine):
410
431
0 commit comments