diff --git a/pandas/core/dtypes/cast.py b/pandas/core/dtypes/cast.py index edc43bc68b2a8..3f3d9f9f2833b 100644 --- a/pandas/core/dtypes/cast.py +++ b/pandas/core/dtypes/cast.py @@ -498,55 +498,6 @@ def maybe_cast_to_extension_array( return result -def maybe_upcast_putmask(result: np.ndarray, mask: np.ndarray) -> np.ndarray: - """ - A safe version of putmask that potentially upcasts the result. - - The result is replaced with the first N elements of other, - where N is the number of True values in mask. - If the length of other is shorter than N, other will be repeated. - - Parameters - ---------- - result : ndarray - The destination array. This will be mutated in-place if no upcasting is - necessary. - mask : np.ndarray[bool] - - Returns - ------- - result : ndarray - - Examples - -------- - >>> arr = np.arange(1, 6) - >>> mask = np.array([False, True, False, True, True]) - >>> result = maybe_upcast_putmask(arr, mask) - >>> result - array([ 1., nan, 3., nan, nan]) - """ - if not isinstance(result, np.ndarray): - raise ValueError("The result input must be a ndarray.") - - # NB: we never get here with result.dtype.kind in ["m", "M"] - - if mask.any(): - - # we want to decide whether place will work - # if we have nans in the False portion of our mask then we need to - # upcast (possibly), otherwise we DON't want to upcast (e.g. if we - # have values, say integers, in the success portion then it's ok to not - # upcast) - new_dtype = ensure_dtype_can_hold_na(result.dtype) - - if new_dtype != result.dtype: - result = result.astype(new_dtype, copy=True) - - np.place(result, mask, np.nan) - - return result - - @overload def ensure_dtype_can_hold_na(dtype: np.dtype) -> np.dtype: ... diff --git a/pandas/core/ops/array_ops.py b/pandas/core/ops/array_ops.py index 5c26377f44c2b..ba9da8d648597 100644 --- a/pandas/core/ops/array_ops.py +++ b/pandas/core/ops/array_ops.py @@ -23,7 +23,6 @@ from pandas.core.dtypes.cast import ( construct_1d_object_array_from_listlike, find_common_type, - maybe_upcast_putmask, ) from pandas.core.dtypes.common import ( ensure_object, @@ -129,7 +128,7 @@ def _masked_arith_op(x: np.ndarray, y, op): if mask.any(): result[mask] = op(xrav[mask], y) - result = maybe_upcast_putmask(result, ~mask) + np.putmask(result, ~mask, np.nan) result = result.reshape(x.shape) # 2D compat return result diff --git a/pandas/tests/dtypes/cast/test_upcast.py b/pandas/tests/dtypes/cast/test_upcast.py deleted file mode 100644 index 89b59ebe6628f..0000000000000 --- a/pandas/tests/dtypes/cast/test_upcast.py +++ /dev/null @@ -1,37 +0,0 @@ -import numpy as np -import pytest - -from pandas.core.dtypes.cast import maybe_upcast_putmask - -from pandas import Series -import pandas._testing as tm - - -@pytest.mark.parametrize("result", [Series([10, 11, 12]), [10, 11, 12], (10, 11, 12)]) -def test_upcast_error(result): - # GH23823 require result arg to be ndarray - mask = np.array([False, True, False]) - with pytest.raises(ValueError, match="The result input must be a ndarray"): - result = maybe_upcast_putmask(result, mask) - - -def test_upcast(): - # GH23823 - arr = np.arange(1, 6) - mask = np.array([False, True, False, True, True]) - result = maybe_upcast_putmask(arr, mask) - - expected = np.array([1, np.nan, 3, np.nan, np.nan]) - tm.assert_numpy_array_equal(result, expected) - - -def test_maybe_upcast_putmask_bool(): - # a case where maybe_upcast_putmask is *not* equivalent to - # try: np.putmask(result, mask, np.nan) - # except (ValueError, TypeError): result = np.where(mask, result, np.nan) - arr = np.array([True, False, True, False, True], dtype=bool) - mask = np.array([False, True, False, True, True]) - result = maybe_upcast_putmask(arr, mask) - - expected = np.array([True, np.nan, True, np.nan, np.nan], dtype=object) - tm.assert_numpy_array_equal(result, expected)