def unstack(self, unstacker, fill_value) -> ArrayManager: """ Return a BlockManager with all blocks unstacked. Parameters ---------- unstacker : reshape._Unstacker fill_value : Any fill_value for newly introduced missing values. Returns ------- unstacked : BlockManager """ indexer, _ = unstacker._indexer_and_to_sort if unstacker.mask.all(): new_indexer = indexer allow_fill = False new_mask2D = None needs_masking = None else: new_indexer = np.full(unstacker.mask.shape, -1) new_indexer[unstacker.mask] = indexer allow_fill = True # calculating the full mask once and passing it to take_1d is faster # than letting take_1d calculate it in each repeated call new_mask2D = (~unstacker.mask).reshape(*unstacker.full_shape) needs_masking = new_mask2D.any(axis=0) new_indexer2D = new_indexer.reshape(*unstacker.full_shape) new_indexer2D = ensure_platform_int(new_indexer2D) new_arrays = [] for arr in self.arrays: for i in range(unstacker.full_shape[1]): if allow_fill: # error: Value of type "Optional[Any]" is not indexable [index] new_arr = take_1d( arr, new_indexer2D[:, i], allow_fill=needs_masking[i], # type: ignore[index] fill_value=fill_value, mask=new_mask2D[:, i], # type: ignore[index] ) else: new_arr = take_1d(arr, new_indexer2D[:, i], allow_fill=False) new_arrays.append(new_arr) new_index = unstacker.new_index new_columns = unstacker.get_new_columns(self._axes[1]) new_axes = [new_index, new_columns] return type(self)(new_arrays, new_axes, verify_integrity=False)
def unstack(self, unstacker, fill_value) -> ArrayManager: """ Return a BlockManager with all blocks unstacked.. Parameters ---------- unstacker : reshape._Unstacker fill_value : Any fill_value for newly introduced missing values. Returns ------- unstacked : BlockManager """ indexer, _ = unstacker._indexer_and_to_sort new_indexer = np.full(unstacker.mask.shape, -1) new_indexer[unstacker.mask] = indexer new_indexer2D = new_indexer.reshape(*unstacker.full_shape) new_arrays = [] for arr in self.arrays: for i in range(unstacker.full_shape[1]): new_arr = take_1d( arr, new_indexer2D[:, i], allow_fill=True, fill_value=fill_value ) new_arrays.append(new_arr) new_index = unstacker.new_index new_columns = unstacker.get_new_columns(self._axes[1]) new_axes = [new_index, new_columns] return type(self)(new_arrays, new_axes, verify_integrity=False)
def _reindex_indexer( self: T, new_axis, indexer, axis: int, fill_value=None, allow_dups: bool = False, copy: bool = True, use_na_proxy: bool = False, ) -> T: """ Parameters ---------- new_axis : Index indexer : ndarray of int64 or None axis : int fill_value : object, default None allow_dups : bool, default False copy : bool, default True pandas-indexer with -1's only. """ if indexer is None: if new_axis is self._axes[axis] and not copy: return self result = self.copy(deep=copy) result._axes = list(self._axes) result._axes[axis] = new_axis return result # some axes don't allow reindexing with dups if not allow_dups: self._axes[axis]._validate_can_reindex(indexer) if axis >= self.ndim: raise IndexError("Requested axis not found in manager") if axis == 1: new_arrays = [] for i in indexer: if i == -1: arr = self._make_na_array(fill_value=fill_value, use_na_proxy=use_na_proxy) else: arr = self.arrays[i] new_arrays.append(arr) else: validate_indices(indexer, len(self._axes[0])) indexer = ensure_platform_int(indexer) if (indexer == -1).any(): allow_fill = True else: allow_fill = False new_arrays = [ take_1d( arr, indexer, allow_fill=allow_fill, fill_value=fill_value, # if fill_value is not None else blk.fill_value ) for arr in self.arrays ] new_axes = list(self._axes) new_axes[axis] = new_axis return type(self)(new_arrays, new_axes, verify_integrity=False)
def _reindex_indexer( self: T, new_axis, indexer, axis: int, fill_value=None, allow_dups: bool = False, copy: bool = True, ) -> T: """ Parameters ---------- new_axis : Index indexer : ndarray of int64 or None axis : int fill_value : object, default None allow_dups : bool, default False copy : bool, default True pandas-indexer with -1's only. """ if indexer is None: if new_axis is self._axes[axis] and not copy: return self result = self.copy(deep=copy) result._axes = list(self._axes) result._axes[axis] = new_axis return result # some axes don't allow reindexing with dups if not allow_dups: self._axes[axis]._validate_can_reindex(indexer) if axis >= self.ndim: raise IndexError("Requested axis not found in manager") if axis == 1: new_arrays = [] for i in indexer: if i == -1: arr = self._make_na_array(fill_value=fill_value) else: arr = self.arrays[i] new_arrays.append(arr) else: validate_indices(indexer, len(self._axes[0])) new_arrays = [ # error: Value of type variable "ArrayLike" of "take_1d" cannot be # "Union[ndarray, ExtensionArray]" [type-var] take_1d( # type: ignore[type-var] arr, indexer, allow_fill=True, fill_value=fill_value, # if fill_value is not None else blk.fill_value ) for arr in self.arrays ] new_axes = list(self._axes) new_axes[axis] = new_axis return type(self)(new_arrays, new_axes, verify_integrity=False)