diff --git a/pandas/_libs/internals.pyx b/pandas/_libs/internals.pyx index db452cb0f1fa4..8b4b490f49b12 100644 --- a/pandas/_libs/internals.pyx +++ b/pandas/_libs/internals.pyx @@ -16,6 +16,7 @@ cnp.import_array() from pandas._libs.algos import ensure_int64 +@cython.final cdef class BlockPlacement: # __slots__ = '_as_slice', '_as_array', '_len' cdef: diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 0c98a779424bd..6207785fb2975 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -8,6 +8,7 @@ from pandas._libs import NaT, algos as libalgos, lib, writers import pandas._libs.internals as libinternals +from pandas._libs.internals import BlockPlacement from pandas._libs.tslibs import conversion from pandas._libs.tslibs.timezones import tz_compare from pandas._typing import ArrayLike @@ -112,6 +113,19 @@ class Block(PandasObject): _verify_integrity = True _validate_ndim = True + @classmethod + def _simple_new( + cls, values: ArrayLike, placement: BlockPlacement, ndim: int + ) -> "Block": + """ + Fastpath constructor, does *no* validation + """ + obj = object.__new__(cls) + obj.ndim = ndim + obj.values = values + obj._mgr_locs = placement + return obj + def __init__(self, values, placement, ndim=None): self.ndim = self._check_ndim(values, ndim) self.mgr_locs = placement @@ -289,13 +303,15 @@ def getitem_block(self, slicer, new_mgr_locs=None): if new_mgr_locs is None: axis0_slicer = slicer[0] if isinstance(slicer, tuple) else slicer new_mgr_locs = self.mgr_locs[axis0_slicer] + elif not isinstance(new_mgr_locs, BlockPlacement): + new_mgr_locs = BlockPlacement(new_mgr_locs) new_values = self._slice(slicer) if self._validate_ndim and new_values.ndim != self.ndim: raise ValueError("Only same dim slicing is allowed") - return self.make_block_same_class(new_values, new_mgr_locs) + return type(self)._simple_new(new_values, new_mgr_locs, self.ndim) @property def shape(self):