def astype(self, dtype: Dtype, copy: bool = True) -> ArrayLike: dtype = pandas_dtype(dtype) if is_dtype_equal(dtype, self.dtype): if copy: # error: Incompatible return value type (got "BaseMaskedArray", expected # "ndarray") return self.copy() # type: ignore[return-value] # error: Incompatible return value type (got "BaseMaskedArray", expected # "ndarray") return self # type: ignore[return-value] # if we are astyping to another nullable masked dtype, we can fastpath if isinstance(dtype, BaseMaskedDtype): # TODO deal with NaNs for FloatingArray case data = self._data.astype(dtype.numpy_dtype, copy=copy) # mask is copied depending on whether the data was copied, and # not directly depending on the `copy` keyword mask = self._mask if data is self._data else self._mask.copy() cls = dtype.construct_array_type() # error: Incompatible return value type (got "BaseMaskedArray", expected # "ndarray") return cls(data, mask, copy=False) # type: ignore[return-value] if isinstance(dtype, ExtensionDtype): eacls = dtype.construct_array_type() return eacls._from_sequence(self, dtype=dtype, copy=copy) raise NotImplementedError("subclass must implement astype to np.dtype")
def _get_counts( values_shape: Tuple[int, ...], mask: Optional[np.ndarray], axis: Optional[int], dtype: Dtype = float, ) -> Union[int, float, np.ndarray]: """ Get the count of non-null values along an axis Parameters ---------- values_shape : tuple of int shape tuple from values ndarray, used if mask is None mask : Optional[ndarray[bool]] locations in values that should be considered missing axis : Optional[int] axis to count along dtype : type, optional type to use for count Returns ------- count : scalar or array """ dtype = _get_dtype(dtype) if axis is None: if mask is not None: n = mask.size - mask.sum() else: n = np.prod(values_shape) return dtype.type(n) if mask is not None: count = mask.shape[axis] - mask.sum(axis) else: count = values_shape[axis] if is_scalar(count): return dtype.type(count) try: return count.astype(dtype) except AttributeError: return np.array(count, dtype=dtype)
def _get_counts_nanvar( value_counts: Tuple[int], mask: Optional[np.ndarray], axis: Optional[int], ddof: int, dtype: Dtype = float, ) -> Tuple[Union[int, np.ndarray], Union[int, np.ndarray]]: """ Get the count of non-null values along an axis, accounting for degrees of freedom. Parameters ---------- values_shape : Tuple[int] shape tuple from values ndarray, used if mask is None mask : Optional[ndarray[bool]] locations in values that should be considered missing axis : Optional[int] axis to count along ddof : int degrees of freedom dtype : type, optional type to use for count Returns ------- count : scalar or array d : scalar or array """ dtype = _get_dtype(dtype) count = _get_counts(value_counts, mask, axis, dtype=dtype) d = count - dtype.type(ddof) # always return NaN, never inf if is_scalar(count): if count <= ddof: count = np.nan d = np.nan else: mask2: np.ndarray = count <= ddof if mask2.any(): np.putmask(d, mask2, np.nan) np.putmask(count, mask2, np.nan) return count, d