diff --git a/doc/source/whatsnew/v1.5.0.rst b/doc/source/whatsnew/v1.5.0.rst index 0b450fab53137..0e5bde5fc29ae 100644 --- a/doc/source/whatsnew/v1.5.0.rst +++ b/doc/source/whatsnew/v1.5.0.rst @@ -910,6 +910,7 @@ Missing - Bug in :meth:`Series.fillna` and :meth:`DataFrame.fillna` with :class:`IntervalDtype` and incompatible value raising instead of casting to a common (usually object) dtype (:issue:`45796`) - Bug in :meth:`DataFrame.interpolate` with object-dtype column not returning a copy with ``inplace=False`` (:issue:`45791`) - Bug in :meth:`DataFrame.dropna` allows to set both ``how`` and ``thresh`` incompatible arguments (:issue:`46575`) +- Bug in :meth:`DataFrame.replace` now works when ``pandas.NA`` is a value in the dara frame (:issue:`47480`) MultiIndex ^^^^^^^^^^ diff --git a/pandas/_libs/missing.pyx b/pandas/_libs/missing.pyx index 9b470e95dc22b..906935bb12aae 100644 --- a/pandas/_libs/missing.pyx +++ b/pandas/_libs/missing.pyx @@ -409,7 +409,6 @@ class NAType(C_NAType): __rdivmod__ = _create_binary_propagating_op("__rdivmod__", is_divmod=True) # __lshift__ and __rshift__ are not implemented - __eq__ = _create_binary_propagating_op("__eq__") __ne__ = _create_binary_propagating_op("__ne__") __le__ = _create_binary_propagating_op("__le__") __lt__ = _create_binary_propagating_op("__lt__") @@ -423,6 +422,12 @@ class NAType(C_NAType): __abs__ = _create_unary_propagating_op("__abs__") __invert__ = _create_unary_propagating_op("__invert__") + def __eq__(self, other): + if other is C_NA: + return True + else: + return False + # pow has special def __pow__(self, other): if other is C_NA: diff --git a/pandas/core/missing.py b/pandas/core/missing.py index 57b0a95f803b1..391921deded1f 100644 --- a/pandas/core/missing.py +++ b/pandas/core/missing.py @@ -93,6 +93,7 @@ def mask_missing(arr: ArrayLike, values_to_mask) -> npt.NDArray[np.bool_]: pass else: new_mask = arr == x + if not isinstance(new_mask, np.ndarray): # usually BooleanArray new_mask = new_mask.to_numpy(dtype=bool, na_value=False) diff --git a/pandas/tests/frame/methods/test_replace.py b/pandas/tests/frame/methods/test_replace.py index f7504e9173bf5..5e2d2d536e6ff 100644 --- a/pandas/tests/frame/methods/test_replace.py +++ b/pandas/tests/frame/methods/test_replace.py @@ -1567,3 +1567,10 @@ def test_replace_with_value_also_being_replaced(self): result = df.replace({0: 1, 1: np.nan}) expected = DataFrame({"A": [1, np.nan, 2], "B": [np.nan, 1, 2]}) tm.assert_frame_equal(result, expected) + + def test_replace_with_pandas_NA(self): + # GH47480 + df = DataFrame({"A": [pd.NA, 1, 2], "B": [1, 0, 2]}) + result = df.replace(2, 3) + expected = DataFrame({"A": [pd.NA, 1, 3], "B": [1, 0, 3]}) + tm.assert_frame_equal(result, expected)