diff --git a/pandas/_libs/internals.pyx b/pandas/_libs/internals.pyx index d69b417f6e056..d3d8bead88d08 100644 --- a/pandas/_libs/internals.pyx +++ b/pandas/_libs/internals.pyx @@ -106,13 +106,8 @@ cdef class BlockPlacement: else: return self._as_array - 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): + def as_array(self) -> np.ndarray: cdef: Py_ssize_t start, stop, end, _ @@ -146,10 +141,10 @@ cdef class BlockPlacement: return BlockPlacement(val) - def delete(self, loc): + def delete(self, loc) -> "BlockPlacement": return BlockPlacement(np.delete(self.as_array, loc, axis=0)) - def append(self, others): + def append(self, others) -> "BlockPlacement": if not len(others): return self @@ -190,12 +185,10 @@ cdef class BlockPlacement: val = newarr return BlockPlacement(val) - def add(self, other): + def add(self, other) -> "BlockPlacement": + # We can get here with int or ndarray return self.iadd(other) - def sub(self, other): - return self.add(-other) - cdef slice _ensure_has_slice(self): if not self._has_slice: self._as_slice = indexer_as_slice(self._as_array) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index f8ecc2509ad10..2df352a8d72a2 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -5305,10 +5305,10 @@ def _check_inplace_setting(self, value) -> bool_t: return True def _get_numeric_data(self): - return self._constructor(self._mgr.get_numeric_data()).__finalize__(self,) + return self._constructor(self._mgr.get_numeric_data()).__finalize__(self) def _get_bool_data(self): - return self._constructor(self._mgr.get_bool_data()).__finalize__(self,) + return self._constructor(self._mgr.get_bool_data()).__finalize__(self) # ---------------------------------------------------------------------- # Internal Interface Methods @@ -6542,21 +6542,16 @@ def replace( if not self.size: return self - new_data = self._mgr if is_dict_like(to_replace): if is_dict_like(value): # {'A' : NA} -> {'A' : 0} - res = self if inplace else self.copy() - for c, src in to_replace.items(): - if c in value and c in self: - # object conversion is handled in - # series.replace which is called recursively - res[c] = res[c].replace( - to_replace=src, - value=value[c], - inplace=False, - regex=regex, - ) - return None if inplace else res + # Note: Checking below for `in foo.keys()` instead of + # `in foo`is needed for when we have a Series and not dict + mapping = { + col: (to_replace[col], value[col]) + for col in to_replace.keys() + if col in value.keys() and col in self + } + return self._replace_columnwise(mapping, inplace, regex) # {'A': NA} -> 0 elif not is_list_like(value): diff --git a/pandas/core/internals/managers.py b/pandas/core/internals/managers.py index f241410b25a82..bfb16b48d832c 100644 --- a/pandas/core/internals/managers.py +++ b/pandas/core/internals/managers.py @@ -110,8 +110,6 @@ class BlockManager(PandasObject): __slots__ = [ "axes", "blocks", - "_ndim", - "_shape", "_known_consolidated", "_is_consolidated", "_blknos", @@ -759,9 +757,7 @@ def get_slice(self, slobj: slice, axis: int = 0) -> "BlockManager": if axis == 0: new_blocks = self._slice_take_blocks_ax0(slobj) elif axis == 1: - _slicer = [slice(None)] * (axis + 1) - _slicer[axis] = slobj - slicer = tuple(_slicer) + slicer = (slice(None), slobj) new_blocks = [blk.getitem_block(slicer) for blk in self.blocks] else: raise IndexError("Requested axis not found in manager") @@ -1103,7 +1099,6 @@ def value_getitem(placement): if len(val_locs) == len(blk.mgr_locs): removed_blknos.append(blkno) else: - self._blklocs[blk.mgr_locs.indexer] = -1 blk.delete(blk_locs) self._blklocs[blk.mgr_locs.indexer] = np.arange(len(blk)) @@ -1115,9 +1110,7 @@ def value_getitem(placement): new_blknos = np.empty(self.nblocks, dtype=np.int64) new_blknos.fill(-1) new_blknos[~is_deleted] = np.arange(self.nblocks - len(removed_blknos)) - self._blknos = algos.take_1d( - new_blknos, self._blknos, axis=0, allow_fill=False - ) + self._blknos = new_blknos[self._blknos] self.blocks = tuple( blk for i, blk in enumerate(self.blocks) if i not in set(removed_blknos) ) @@ -1128,8 +1121,9 @@ def value_getitem(placement): new_blocks: List[Block] = [] if value_is_extension_type: - # This code (ab-)uses the fact that sparse blocks contain only + # This code (ab-)uses the fact that EA blocks contain only # one item. + # TODO(EA2D): special casing unnecessary with 2D EAs new_blocks.extend( make_block( values=value, @@ -1162,7 +1156,7 @@ def value_getitem(placement): # Newly created block's dtype may already be present. self._known_consolidated = False - def insert(self, loc: int, item, value, allow_duplicates: bool = False): + def insert(self, loc: int, item: Label, value, allow_duplicates: bool = False): """ Insert item at selected position. @@ -1185,7 +1179,7 @@ def insert(self, loc: int, item, value, allow_duplicates: bool = False): # insert to the axis; this could possibly raise a TypeError new_axis = self.items.insert(loc, item) - if value.ndim == self.ndim - 1 and not is_extension_array_dtype(value): + if value.ndim == self.ndim - 1 and not is_extension_array_dtype(value.dtype): value = _safe_reshape(value, (1,) + value.shape) block = make_block(values=value, ndim=self.ndim, placement=slice(loc, loc + 1)) @@ -1959,14 +1953,14 @@ def _compare_or_regex_search(a, b, regex=False): return result -def _fast_count_smallints(arr): +def _fast_count_smallints(arr: np.ndarray) -> np.ndarray: """Faster version of set(arr) for sequences of small numbers.""" counts = np.bincount(arr.astype(np.int_)) nz = counts.nonzero()[0] return np.c_[nz, counts[nz]] -def _preprocess_slice_or_indexer(slice_or_indexer, length, allow_fill): +def _preprocess_slice_or_indexer(slice_or_indexer, length: int, allow_fill: bool): if isinstance(slice_or_indexer, slice): return ( "slice",