diff --git a/pandas/_libs/internals.pyx b/pandas/_libs/internals.pyx index 3bebd7e23fb5a..d69b417f6e056 100644 --- a/pandas/_libs/internals.pyx +++ b/pandas/_libs/internals.pyx @@ -20,7 +20,6 @@ cdef class BlockPlacement: cdef: slice _as_slice object _as_array - bint _has_slice, _has_array, _is_known_slice_like def __init__(self, val): @@ -56,12 +55,13 @@ cdef class BlockPlacement: def __str__(self) -> str: cdef: slice s = self._ensure_has_slice() + if s is not None: v = self._as_slice else: v = self._as_array - return f'{type(self).__name__}({v})' + return f"{type(self).__name__}({v})" def __repr__(self) -> str: return str(self) @@ -69,6 +69,7 @@ cdef class BlockPlacement: def __len__(self) -> int: cdef: slice s = self._ensure_has_slice() + if s is not None: return slice_len(s) else: @@ -78,6 +79,7 @@ cdef class BlockPlacement: cdef: slice s = self._ensure_has_slice() Py_ssize_t start, stop, step, _ + if s is not None: start, stop, step, _ = slice_get_indices_ex(s) return iter(range(start, stop, step)) @@ -88,15 +90,17 @@ cdef class BlockPlacement: def as_slice(self) -> slice: cdef: slice s = self._ensure_has_slice() - if s is None: - raise TypeError('Not slice-like') - else: + + if s is not None: return s + else: + raise TypeError("Not slice-like") @property def indexer(self): cdef: slice s = self._ensure_has_slice() + if s is not None: return s else: @@ -104,29 +108,34 @@ cdef class BlockPlacement: def isin(self, arr): from pandas.core.indexes.api import Int64Index + return Int64Index(self.as_array, copy=False).isin(arr) @property def as_array(self): cdef: Py_ssize_t start, stop, end, _ + if not self._has_array: start, stop, step, _ = slice_get_indices_ex(self._as_slice) # NOTE: this is the C-optimized equivalent of - # np.arange(start, stop, step, dtype=np.int64) + # `np.arange(start, stop, step, dtype=np.int64)` self._as_array = cnp.PyArray_Arange(start, stop, step, NPY_INT64) self._has_array = True + return self._as_array @property def is_slice_like(self) -> bool: cdef: slice s = self._ensure_has_slice() + return s is not None def __getitem__(self, loc): cdef: slice s = self._ensure_has_slice() + if s is not None: val = slice_getitem(s, loc) else: @@ -141,11 +150,12 @@ cdef class BlockPlacement: return BlockPlacement(np.delete(self.as_array, loc, axis=0)) def append(self, others): - if len(others) == 0: + if not len(others): return self - return BlockPlacement(np.concatenate([self.as_array] + - [o.as_array for o in others])) + return BlockPlacement( + np.concatenate([self.as_array] + [o.as_array for o in others]) + ) cdef iadd(self, other): cdef: @@ -163,8 +173,7 @@ cdef class BlockPlacement: start += other_int stop += other_int - if ((step > 0 and start < 0) or - (step < 0 and stop < step)): + if (step > 0 and start < 0) or (step < 0 and stop < step): raise ValueError("iadd causes length change") if stop < 0: @@ -191,6 +200,7 @@ cdef class BlockPlacement: if not self._has_slice: self._as_slice = indexer_as_slice(self._as_array) self._has_slice = True + return self._as_slice @@ -240,8 +250,7 @@ cdef slice slice_canonize(slice s): return slice(start, stop, step) -cpdef Py_ssize_t slice_len( - slice slc, Py_ssize_t objlen=PY_SSIZE_T_MAX) except -1: +cpdef Py_ssize_t slice_len(slice slc, Py_ssize_t objlen=PY_SSIZE_T_MAX) except -1: """ Get length of a bounded slice. @@ -258,8 +267,7 @@ cpdef Py_ssize_t slice_len( if slc is None: raise TypeError("slc must be slice") - PySlice_GetIndicesEx(slc, objlen, - &start, &stop, &step, &length) + PySlice_GetIndicesEx(slc, objlen, &start, &stop, &step, &length) return length @@ -277,8 +285,7 @@ cdef slice_get_indices_ex(slice slc, Py_ssize_t objlen=PY_SSIZE_T_MAX): if slc is None: raise TypeError("slc should be a slice") - PySlice_GetIndicesEx(slc, objlen, - &start, &stop, &step, &length) + PySlice_GetIndicesEx(slc, objlen, &start, &stop, &step, &length) return start, stop, step, length @@ -378,8 +385,7 @@ def get_blkno_indexers(int64_t[:] blknos, bint group=True): # blockno handling. cdef: int64_t cur_blkno - Py_ssize_t i, start, stop, n, diff - + Py_ssize_t i, start, stop, n, diff, tot_len object blkno object group_dict = defaultdict(list)