def test_can_hold_element_int_values_float_ndarray(): arr = np.array([], dtype=np.int64) element = np.array([1.0, 2.0]) assert can_hold_element(arr, element) assert not can_hold_element(arr, element + 0.5) # integer but not losslessly castable to int64 element = np.array([3, 2**65], dtype=np.float64) assert not can_hold_element(arr, element)
def test_can_hold_element_int8_int(): arr = np.array([], dtype=np.int8) element = 2 assert can_hold_element(arr, element) assert can_hold_element(arr, np.int8(element)) assert can_hold_element(arr, np.uint8(element)) assert can_hold_element(arr, np.int16(element)) assert can_hold_element(arr, np.uint16(element)) assert can_hold_element(arr, np.int32(element)) assert can_hold_element(arr, np.uint32(element)) assert can_hold_element(arr, np.int64(element)) assert can_hold_element(arr, np.uint64(element))
def putmask_smart(values: np.ndarray, mask: npt.NDArray[np.bool_], new) -> np.ndarray: """ Return a new ndarray, try to preserve dtype if possible. Parameters ---------- values : np.ndarray `values`, updated in-place. mask : np.ndarray[bool] Applies to both sides (array like). new : listlike `new values` aligned with `values` Returns ------- values : ndarray with updated values this *may* be a copy of the original See Also -------- np.putmask """ # we cannot use np.asarray() here as we cannot have conversions # that numpy does when numeric are mixed with strings # see if we are only masking values that if putted # will work in the current dtype try: nn = new[mask] except TypeError: # TypeError: only integer scalar arrays can be converted to a scalar index pass else: # We only get to putmask_smart when we cannot hold 'new' in values. # The "smart" part of putmask_smart is checking if we can hold new[mask] # in values, in which case we can still avoid the need to cast. if can_hold_element(values, nn): values[mask] = nn return values new = np.asarray(new) if values.dtype.kind == new.dtype.kind: # preserves dtype if possible np.putmask(values, mask, new) return values dtype = find_common_type([values.dtype, new.dtype]) # error: Argument 1 to "astype" of "_ArrayOrScalarCommon" has incompatible type # "Union[dtype[Any], ExtensionDtype]"; expected "Union[dtype[Any], None, type, # _SupportsDType, str, Union[Tuple[Any, int], Tuple[Any, Union[int, Sequence[int]]], # List[Any], _DTypeDict, Tuple[Any, Any]]]" values = values.astype(dtype) # type: ignore[arg-type] np.putmask(values, mask, new) return values
def putmask_smart(values: np.ndarray, mask: npt.NDArray[np.bool_], new) -> np.ndarray: """ Return a new ndarray, try to preserve dtype if possible. Parameters ---------- values : np.ndarray `values`, updated in-place. mask : np.ndarray[bool] Applies to both sides (array like). new : listlike `new values` aligned with `values` Returns ------- values : ndarray with updated values this *may* be a copy of the original See Also -------- np.putmask """ # we cannot use np.asarray() here as we cannot have conversions # that numpy does when numeric are mixed with strings # see if we are only masking values that if putted # will work in the current dtype try: nn = new[mask] except TypeError: # TypeError: only integer scalar arrays can be converted to a scalar index pass else: # We only get to putmask_smart when we cannot hold 'new' in values. # The "smart" part of putmask_smart is checking if we can hold new[mask] # in values, in which case we can still avoid the need to cast. if can_hold_element(values, nn): values[mask] = nn return values new = np.asarray(new) if values.dtype.kind == new.dtype.kind: # preserves dtype if possible np.putmask(values, mask, new) return values dtype = find_common_type([values.dtype, new.dtype]) values = values.astype(dtype) np.putmask(values, mask, new) return values
def test_can_hold_element_range(any_int_numpy_dtype): # GH#44261 dtype = np.dtype(any_int_numpy_dtype) arr = np.array([], dtype=dtype) rng = range(2, 127) assert can_hold_element(arr, rng) # negatives -> can't be held by uint dtypes rng = range(-2, 127) if dtype.kind == "i": assert can_hold_element(arr, rng) else: assert not can_hold_element(arr, rng) rng = range(2, 255) if dtype == "int8": assert not can_hold_element(arr, rng) else: assert can_hold_element(arr, rng) rng = range(-255, 65537) if dtype.kind == "u": assert not can_hold_element(arr, rng) elif dtype.itemsize < 4: assert not can_hold_element(arr, rng) else: assert can_hold_element(arr, rng) # empty rng = range(-(10**10), -(10**10)) assert len(rng) == 0 # assert can_hold_element(arr, rng) rng = range(10**10, 10**10) assert len(rng) == 0 assert can_hold_element(arr, rng)
def _can_hold_element_patched(obj, element) -> bool: if isinstance(element, PandasArray): element = element.to_numpy() return can_hold_element(obj, element)