Skip to content

Commit ef97dd4

Browse files
authored
REF: unify i8 casting in DatetimeEngine (#43679)
1 parent 2c511dc commit ef97dd4

File tree

4 files changed

+19
-48
lines changed

4 files changed

+19
-48
lines changed

pandas/_libs/index.pyx

+10-45
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ cdef class IndexEngine:
8484
if self.over_size_threshold and self.is_monotonic_increasing:
8585
if not self.is_unique:
8686
return self._get_loc_duplicates(val)
87-
values = self._get_index_values()
87+
values = self.values
8888

8989
self._check_type(val)
9090
try:
@@ -116,7 +116,7 @@ cdef class IndexEngine:
116116
Py_ssize_t diff
117117

118118
if self.is_monotonic_increasing:
119-
values = self._get_index_values()
119+
values = self.values
120120
try:
121121
left = values.searchsorted(val, side='left')
122122
right = values.searchsorted(val, side='right')
@@ -139,7 +139,7 @@ cdef class IndexEngine:
139139
cdef:
140140
ndarray[uint8_t, ndim=1, cast=True] indexer
141141

142-
indexer = self._get_index_values() == val
142+
indexer = self.values == val
143143
return self._unpack_bool_indexer(indexer, val)
144144

145145
cdef _unpack_bool_indexer(self,
@@ -199,7 +199,7 @@ cdef class IndexEngine:
199199
cdef:
200200
bint is_unique
201201
try:
202-
values = self._get_index_values()
202+
values = self.values
203203
self.monotonic_inc, self.monotonic_dec, is_unique = \
204204
self._call_monotonic(values)
205205
except TypeError:
@@ -214,17 +214,14 @@ cdef class IndexEngine:
214214
self.unique = 1
215215
self.need_unique_check = 0
216216

217-
cdef ndarray _get_index_values(self):
218-
return self.values
219-
220217
cdef _call_monotonic(self, values):
221218
return algos.is_monotonic(values, timelike=False)
222219

223220
def get_backfill_indexer(self, other: np.ndarray, limit=None) -> np.ndarray:
224-
return algos.backfill(self._get_index_values(), other, limit=limit)
221+
return algos.backfill(self.values, other, limit=limit)
225222

226223
def get_pad_indexer(self, other: np.ndarray, limit=None) -> np.ndarray:
227-
return algos.pad(self._get_index_values(), other, limit=limit)
224+
return algos.pad(self.values, other, limit=limit)
228225

229226
cdef _make_hash_table(self, Py_ssize_t n):
230227
raise NotImplementedError
@@ -243,7 +240,7 @@ cdef class IndexEngine:
243240

244241
if not self.is_mapping_populated:
245242

246-
values = self._get_index_values()
243+
values = self.values
247244
self.mapping = self._make_hash_table(len(values))
248245
self._call_map_locations(values)
249246

@@ -291,7 +288,7 @@ cdef class IndexEngine:
291288
bint d_has_nan = False, stargets_has_nan = False, need_nan_check = True
292289

293290
self._ensure_mapping_populated()
294-
values = np.array(self._get_index_values(), copy=False)
291+
values = self.values
295292
stargets = set(targets)
296293

297294
n = len(values)
@@ -411,9 +408,6 @@ cdef class ObjectEngine(IndexEngine):
411408

412409
cdef class DatetimeEngine(Int64Engine):
413410

414-
cdef str _get_box_dtype(self):
415-
return 'M8[ns]'
416-
417411
cdef int64_t _unbox_scalar(self, scalar) except? -1:
418412
# NB: caller is responsible for ensuring tzawareness compat
419413
# before we get here
@@ -431,16 +425,13 @@ cdef class DatetimeEngine(Int64Engine):
431425
if self.over_size_threshold and self.is_monotonic_increasing:
432426
if not self.is_unique:
433427
return self._get_loc_duplicates(conv)
434-
values = self._get_index_values()
428+
values = self.values
435429
loc = values.searchsorted(conv, side='left')
436430
return values[loc] == conv
437431

438432
self._ensure_mapping_populated()
439433
return conv in self.mapping
440434

441-
cdef ndarray _get_index_values(self):
442-
return self.values.view('i8')
443-
444435
cdef _call_monotonic(self, values):
445436
return algos.is_monotonic(values, timelike=True)
446437

@@ -462,7 +453,7 @@ cdef class DatetimeEngine(Int64Engine):
462453
if self.over_size_threshold and self.is_monotonic_increasing:
463454
if not self.is_unique:
464455
return self._get_loc_duplicates(conv)
465-
values = self._get_index_values()
456+
values = self.values
466457

467458
loc = values.searchsorted(conv, side='left')
468459

@@ -479,35 +470,9 @@ cdef class DatetimeEngine(Int64Engine):
479470
except KeyError:
480471
raise KeyError(val)
481472

482-
def get_indexer_non_unique(self, ndarray targets):
483-
# we may get datetime64[ns] or timedelta64[ns], cast these to int64
484-
return super().get_indexer_non_unique(targets.view("i8"))
485-
486-
def get_indexer(self, ndarray values) -> np.ndarray:
487-
self._ensure_mapping_populated()
488-
if values.dtype != self._get_box_dtype():
489-
return np.repeat(-1, len(values)).astype(np.intp)
490-
values = np.asarray(values).view('i8')
491-
return self.mapping.lookup(values)
492-
493-
def get_pad_indexer(self, other: np.ndarray, limit=None) -> np.ndarray:
494-
if other.dtype != self._get_box_dtype():
495-
return np.repeat(-1, len(other)).astype(np.intp)
496-
other = np.asarray(other).view('i8')
497-
return algos.pad(self._get_index_values(), other, limit=limit)
498-
499-
def get_backfill_indexer(self, other: np.ndarray, limit=None) -> np.ndarray:
500-
if other.dtype != self._get_box_dtype():
501-
return np.repeat(-1, len(other)).astype(np.intp)
502-
other = np.asarray(other).view('i8')
503-
return algos.backfill(self._get_index_values(), other, limit=limit)
504-
505473

506474
cdef class TimedeltaEngine(DatetimeEngine):
507475

508-
cdef str _get_box_dtype(self):
509-
return 'm8[ns]'
510-
511476
cdef int64_t _unbox_scalar(self, scalar) except? -1:
512477
if not (isinstance(scalar, _Timedelta) or scalar is NaT):
513478
raise TypeError(scalar)

pandas/_libs/index_class_helper.pxi.in

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ cdef class {{name}}Engine(IndexEngine):
5555

5656
self._check_type(val)
5757

58-
values = self._get_index_values()
58+
values = self.values
5959
try:
6060
with warnings.catch_warnings():
6161
# e.g. if values is float64 and `val` is a str, suppress warning

pandas/core/indexes/base.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -890,7 +890,12 @@ def ravel(self, order="C"):
890890
FutureWarning,
891891
stacklevel=2,
892892
)
893-
values = self._get_engine_target()
893+
if needs_i8_conversion(self.dtype):
894+
# Item "ndarray[Any, Any]" of "Union[ExtensionArray, ndarray[Any, Any]]"
895+
# has no attribute "_ndarray"
896+
values = self._data._ndarray # type: ignore[union-attr]
897+
else:
898+
values = self._get_engine_target()
894899
return values.ravel(order=order)
895900

896901
def view(self, cls=None):

pandas/core/indexes/datetimelike.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,8 @@ def _wrap_joined_index(self, joined, other):
503503
result._data._freq = self._get_join_freq(other)
504504
return result
505505

506-
def _get_join_target(self) -> np.ndarray:
506+
def _get_engine_target(self) -> np.ndarray:
507+
# engine methods and libjoin methods need dt64/td64 values cast to i8
507508
return self._data._ndarray.view("i8")
508509

509510
def _from_join_target(self, result: np.ndarray):

0 commit comments

Comments
 (0)