Skip to content

Commit b176dcd

Browse files
authored
PERF: implement get_slice in cython (#41045)
1 parent 503ce50 commit b176dcd

File tree

3 files changed

+30
-16
lines changed

3 files changed

+30
-16
lines changed

pandas/_libs/internals.pyi

+2
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,5 @@ class BlockManager:
7979
_blklocs: np.ndarray
8080

8181
def __init__(self, blocks: tuple[B, ...], axes: list[Index], verify_integrity=True): ...
82+
83+
def get_slice(self: T, slobj: slice, axis: int=...) -> T: ...

pandas/_libs/internals.pyx

+28-1
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ cdef class NumpyBlock(SharedBlock):
515515
self.values = values
516516

517517
# @final # not useful in cython, but we _would_ annotate with @final
518-
def getitem_block_index(self, slicer: slice) -> NumpyBlock:
518+
cpdef NumpyBlock getitem_block_index(self, slice slicer):
519519
"""
520520
Perform __getitem__-like specialized to slicing along index.
521521
@@ -610,3 +610,30 @@ cdef class BlockManager:
610610
self._rebuild_blknos_and_blklocs()
611611

612612
# -------------------------------------------------------------------
613+
# Indexing
614+
615+
cdef BlockManager _get_index_slice(self, slobj):
616+
cdef:
617+
SharedBlock blk, nb
618+
619+
nbs = []
620+
for blk in self.blocks:
621+
nb = blk.getitem_block_index(slobj)
622+
nbs.append(nb)
623+
624+
new_axes = [self.axes[0], self.axes[1]._getitem_slice(slobj)]
625+
return type(self)(tuple(nbs), new_axes, verify_integrity=False)
626+
627+
def get_slice(self, slobj: slice, axis: int = 0) -> BlockManager:
628+
629+
if axis == 0:
630+
new_blocks = self._slice_take_blocks_ax0(slobj)
631+
elif axis == 1:
632+
return self._get_index_slice(slobj)
633+
else:
634+
raise IndexError("Requested axis not found in manager")
635+
636+
new_axes = list(self.axes)
637+
new_axes[axis] = new_axes[axis]._getitem_slice(slobj)
638+
639+
return type(self)(tuple(new_blocks), new_axes, verify_integrity=False)

pandas/core/internals/managers.py

-15
Original file line numberDiff line numberDiff line change
@@ -1116,21 +1116,6 @@ def fast_xs(self, loc: int) -> ArrayLike:
11161116

11171117
return result
11181118

1119-
def get_slice(self, slobj: slice, axis: int = 0) -> BlockManager:
1120-
assert isinstance(slobj, slice), type(slobj)
1121-
1122-
if axis == 0:
1123-
new_blocks = self._slice_take_blocks_ax0(slobj)
1124-
elif axis == 1:
1125-
new_blocks = [blk.getitem_block_index(slobj) for blk in self.blocks]
1126-
else:
1127-
raise IndexError("Requested axis not found in manager")
1128-
1129-
new_axes = list(self.axes)
1130-
new_axes[axis] = new_axes[axis]._getitem_slice(slobj)
1131-
1132-
return type(self)(tuple(new_blocks), new_axes, verify_integrity=False)
1133-
11341119
def iget(self, i: int) -> SingleBlockManager:
11351120
"""
11361121
Return the data as a SingleBlockManager.

0 commit comments

Comments
 (0)