diff --git a/pandas/_libs/index.pyx b/pandas/_libs/index.pyx index 5ea0108d87c9a..4185cc2084469 100644 --- a/pandas/_libs/index.pyx +++ b/pandas/_libs/index.pyx @@ -1,17 +1,12 @@ -from datetime import datetime, timedelta, date import warnings -import cython - import numpy as np cimport numpy as cnp from numpy cimport (ndarray, intp_t, float64_t, float32_t, int64_t, int32_t, int16_t, int8_t, - uint64_t, uint32_t, uint16_t, uint8_t, - # Note: NPY_DATETIME, NPY_TIMEDELTA are only available - # for cimport in cython>=0.27.3 - NPY_DATETIME, NPY_TIMEDELTA) + uint64_t, uint32_t, uint16_t, uint8_t +) cnp.import_array() @@ -23,7 +18,7 @@ from pandas._libs.tslibs.c_timestamp cimport _Timestamp from pandas._libs.hashtable cimport HashTable from pandas._libs import algos, hashtable as _hash -from pandas._libs.tslibs import Timestamp, Timedelta, period as periodlib +from pandas._libs.tslibs import Timedelta, period as periodlib from pandas._libs.missing import checknull @@ -35,16 +30,6 @@ cdef inline bint is_definitely_invalid_key(object val): return False -cpdef get_value_at(ndarray arr, object loc, object tz=None): - obj = util.get_value_at(arr, loc) - - if arr.descr.type_num == NPY_DATETIME: - return Timestamp(obj, tz=tz) - elif arr.descr.type_num == NPY_TIMEDELTA: - return Timedelta(obj) - return obj - - # Don't populate hash tables in monotonic indexes larger than this _SIZE_CUTOFF = 1_000_000 @@ -72,21 +57,6 @@ cdef class IndexEngine: self._ensure_mapping_populated() return val in self.mapping - cpdef get_value(self, ndarray arr, object key, object tz=None): - """ - Parameters - ---------- - arr : 1-dimensional ndarray - """ - cdef: - object loc - - loc = self.get_loc(key) - if isinstance(loc, slice) or util.is_array(loc): - return arr[loc] - else: - return get_value_at(arr, loc, tz=tz) - cpdef get_loc(self, object val): cdef: Py_ssize_t loc diff --git a/pandas/_libs/util.pxd b/pandas/_libs/util.pxd index 15fedbb20beec..828bccf7d5641 100644 --- a/pandas/_libs/util.pxd +++ b/pandas/_libs/util.pxd @@ -1,7 +1,5 @@ from pandas._libs.tslibs.util cimport * -from cython cimport Py_ssize_t - cimport numpy as cnp from numpy cimport ndarray @@ -51,49 +49,3 @@ cdef inline void set_array_not_contiguous(ndarray ao) nogil: PyArray_CLEARFLAGS(ao, (NPY_ARRAY_C_CONTIGUOUS | NPY_ARRAY_F_CONTIGUOUS)) - -cdef inline Py_ssize_t validate_indexer(ndarray arr, object loc) except -1: - """ - Cast the given indexer `loc` to an integer. If it is negative, i.e. a - python-style indexing-from-the-end indexer, translate it to a - from-the-front indexer. Raise if this is not possible. - - Parameters - ---------- - arr : ndarray - loc : object - - Returns - ------- - idx : Py_ssize_t - - Raises - ------ - IndexError - """ - cdef: - Py_ssize_t idx, size - int casted - - if is_float_object(loc): - casted = int(loc) - if casted == loc: - loc = casted - - idx = loc - size = cnp.PyArray_SIZE(arr) - - if idx < 0 and size > 0: - idx += size - if idx >= size or size == 0 or idx < 0: - raise IndexError('index out of bounds') - - return idx - - -cdef inline object get_value_at(ndarray arr, object loc): - cdef: - Py_ssize_t i - - i = validate_indexer(arr, loc) - return arr[i] diff --git a/pandas/core/arrays/sparse/array.py b/pandas/core/arrays/sparse/array.py index b476a019c66cc..8008805ddcf87 100644 --- a/pandas/core/arrays/sparse/array.py +++ b/pandas/core/arrays/sparse/array.py @@ -9,7 +9,7 @@ import numpy as np -from pandas._libs import index as libindex, lib +from pandas._libs import lib import pandas._libs.sparse as splib from pandas._libs.sparse import BlockIndex, IntIndex, SparseIndex from pandas._libs.tslibs import NaT @@ -794,7 +794,9 @@ def _get_val_at(self, loc): if sp_loc == -1: return self.fill_value else: - return libindex.get_value_at(self.sp_values, sp_loc) + val = self.sp_values[sp_loc] + val = com.maybe_box_datetimelike(val, self.sp_values.dtype) + return val def take(self, indices, allow_fill=False, fill_value=None): if is_scalar(indices): diff --git a/pandas/core/common.py b/pandas/core/common.py index 745a56ce2be7f..00c7a41477017 100644 --- a/pandas/core/common.py +++ b/pandas/core/common.py @@ -72,8 +72,12 @@ def consensus_name_attr(objs): return name -def maybe_box_datetimelike(value): +def maybe_box_datetimelike(value, dtype=None): # turn a datetime like into a Timestamp/timedelta as needed + if dtype == object: + # If we dont have datetime64/timedelta64 dtype, we dont want to + # box datetimelike scalars + return value if isinstance(value, (np.datetime64, datetime)): value = tslibs.Timestamp(value) diff --git a/pandas/tests/indexes/multi/test_get_set.py b/pandas/tests/indexes/multi/test_get_set.py index 57d16a739c213..675a1e2e832f3 100644 --- a/pandas/tests/indexes/multi/test_get_set.py +++ b/pandas/tests/indexes/multi/test_get_set.py @@ -57,8 +57,6 @@ def test_get_value_duplicates(): ) assert index.get_loc("D") == slice(0, 3) - with pytest.raises(KeyError, match=r"^'D'$"): - index._engine.get_value(np.array([]), "D") def test_get_level_values_all_na():