Skip to content

Commit 2b2e9b6

Browse files
authored
PERF: avoid double-verify of take indices (#40391)
1 parent 9612aec commit 2b2e9b6

File tree

3 files changed

+22
-18
lines changed

3 files changed

+22
-18
lines changed

pandas/core/indexers.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ def validate_indices(indices: np.ndarray, n: int) -> None:
235235
# Indexer Conversion
236236

237237

238-
def maybe_convert_indices(indices, n: int):
238+
def maybe_convert_indices(indices, n: int, verify: bool = True):
239239
"""
240240
Attempt to convert indices into valid, positive indices.
241241
@@ -248,6 +248,8 @@ def maybe_convert_indices(indices, n: int):
248248
Array of indices that we are to convert.
249249
n : int
250250
Number of elements in the array that we are indexing.
251+
verify : bool, default True
252+
Check that all entries are between 0 and n - 1, inclusive.
251253
252254
Returns
253255
-------
@@ -273,9 +275,10 @@ def maybe_convert_indices(indices, n: int):
273275
indices = indices.copy()
274276
indices[mask] += n
275277

276-
mask = (indices >= n) | (indices < 0)
277-
if mask.any():
278-
raise IndexError("indices are out-of-bounds")
278+
if verify:
279+
mask = (indices >= n) | (indices < 0)
280+
if mask.any():
281+
raise IndexError("indices are out-of-bounds")
279282
return indices
280283

281284

pandas/core/internals/array_manager.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,7 +1021,7 @@ def _reindex_indexer(
10211021

10221022
return type(self)(new_arrays, new_axes, verify_integrity=False)
10231023

1024-
def take(self, indexer, axis: int = 1, verify: bool = True, convert: bool = True):
1024+
def take(self: T, indexer, axis: int = 1, verify: bool = True) -> T:
10251025
"""
10261026
Take items along any axis.
10271027
"""
@@ -1034,12 +1034,7 @@ def take(self, indexer, axis: int = 1, verify: bool = True, convert: bool = True
10341034
)
10351035

10361036
n = self.shape_proper[axis]
1037-
if convert:
1038-
indexer = maybe_convert_indices(indexer, n)
1039-
1040-
if verify:
1041-
if ((indexer == -1) | (indexer >= n)).any():
1042-
raise Exception("Indices must be nonzero and less than the axis length")
1037+
indexer = maybe_convert_indices(indexer, n, verify=verify)
10431038

10441039
new_labels = self._axes[axis].take(indexer)
10451040
return self._reindex_indexer(

pandas/core/internals/managers.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1491,23 +1491,29 @@ def _make_na_block(self, placement, fill_value=None):
14911491
block_values.fill(fill_value)
14921492
return new_block(block_values, placement=placement, ndim=block_values.ndim)
14931493

1494-
def take(self, indexer, axis: int = 1, verify: bool = True, convert: bool = True):
1494+
def take(self: T, indexer, axis: int = 1, verify: bool = True) -> T:
14951495
"""
14961496
Take items along any axis.
1497+
1498+
indexer : np.ndarray or slice
1499+
axis : int, default 1
1500+
verify : bool, default True
1501+
Check that all entries are between 0 and len(self) - 1, inclusive.
1502+
Pass verify=False if this check has been done by the caller.
1503+
1504+
Returns
1505+
-------
1506+
BlockManager
14971507
"""
1508+
# We have 6 tests that get here with a slice
14981509
indexer = (
14991510
np.arange(indexer.start, indexer.stop, indexer.step, dtype="int64")
15001511
if isinstance(indexer, slice)
15011512
else np.asanyarray(indexer, dtype="int64")
15021513
)
15031514

15041515
n = self.shape[axis]
1505-
if convert:
1506-
indexer = maybe_convert_indices(indexer, n)
1507-
1508-
if verify:
1509-
if ((indexer == -1) | (indexer >= n)).any():
1510-
raise Exception("Indices must be nonzero and less than the axis length")
1516+
indexer = maybe_convert_indices(indexer, n, verify=verify)
15111517

15121518
new_labels = self.axes[axis].take(indexer)
15131519
return self.reindex_indexer(

0 commit comments

Comments
 (0)