Skip to content

Commit ea4431c

Browse files
jbrockmendelvictor
authored and
victor
committed
CLN: de-duplicate index validation code (pandas-dev#22329)
1 parent 630eb02 commit ea4431c

File tree

2 files changed

+37
-36
lines changed

2 files changed

+37
-36
lines changed

pandas/_libs/index.pyx

+1-17
Original file line numberDiff line numberDiff line change
@@ -50,23 +50,7 @@ cpdef get_value_at(ndarray arr, object loc, object tz=None):
5050

5151

5252
cpdef object get_value_box(ndarray arr, object loc):
53-
cdef:
54-
Py_ssize_t i, sz
55-
56-
if util.is_float_object(loc):
57-
casted = int(loc)
58-
if casted == loc:
59-
loc = casted
60-
i = <Py_ssize_t> loc
61-
sz = cnp.PyArray_SIZE(arr)
62-
63-
if i < 0 and sz > 0:
64-
i += sz
65-
66-
if i >= sz or sz == 0 or i < 0:
67-
raise IndexError('index out of bounds')
68-
69-
return get_value_at(arr, i, tz=None)
53+
return get_value_at(arr, loc, tz=None)
7054

7155

7256
# Don't populate hash tables in monotonic indexes larger than this

pandas/_libs/util.pxd

+36-19
Original file line numberDiff line numberDiff line change
@@ -72,23 +72,50 @@ cdef inline void set_array_not_contiguous(ndarray ao) nogil:
7272
(NPY_ARRAY_C_CONTIGUOUS | NPY_ARRAY_F_CONTIGUOUS))
7373

7474

75-
cdef inline object get_value_at(ndarray arr, object loc):
75+
cdef inline Py_ssize_t validate_indexer(ndarray arr, object loc) except -1:
76+
"""
77+
Cast the given indexer `loc` to an integer. If it is negative, i.e. a
78+
python-style indexing-from-the-end indexer, translate it to a
79+
from-the-front indexer. Raise if this is not possible.
80+
81+
Parameters
82+
----------
83+
arr : ndarray
84+
loc : object
85+
86+
Returns
87+
-------
88+
idx : Py_ssize_t
89+
90+
Raises
91+
------
92+
IndexError
93+
"""
7694
cdef:
77-
Py_ssize_t i, sz
95+
Py_ssize_t idx, size
7896
int casted
7997

8098
if is_float_object(loc):
8199
casted = int(loc)
82100
if casted == loc:
83101
loc = casted
84-
i = <Py_ssize_t> loc
85-
sz = cnp.PyArray_SIZE(arr)
86102

87-
if i < 0 and sz > 0:
88-
i += sz
89-
elif i >= sz or sz == 0:
103+
idx = <Py_ssize_t>loc
104+
size = cnp.PyArray_SIZE(arr)
105+
106+
if idx < 0 and size > 0:
107+
idx += size
108+
if idx >= size or size == 0 or idx < 0:
90109
raise IndexError('index out of bounds')
91110

111+
return idx
112+
113+
114+
cdef inline object get_value_at(ndarray arr, object loc):
115+
cdef:
116+
Py_ssize_t i
117+
118+
i = validate_indexer(arr, loc)
92119
return get_value_1d(arr, i)
93120

94121

@@ -99,19 +126,9 @@ cdef inline set_value_at_unsafe(ndarray arr, object loc, object value):
99126
flag above the loop and then eschew the check on each iteration.
100127
"""
101128
cdef:
102-
Py_ssize_t i, sz
103-
if is_float_object(loc):
104-
casted = int(loc)
105-
if casted == loc:
106-
loc = casted
107-
i = <Py_ssize_t> loc
108-
sz = cnp.PyArray_SIZE(arr)
109-
110-
if i < 0:
111-
i += sz
112-
elif i >= sz:
113-
raise IndexError('index out of bounds')
129+
Py_ssize_t i
114130

131+
i = validate_indexer(arr, loc)
115132
assign_value_1d(arr, i, value)
116133

117134

0 commit comments

Comments
 (0)