diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 5f0b0aba2d17c..1ed7fe8a8dad2 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -668,6 +668,7 @@ def replace( # go through replace_list values = self.values + value = self._standardize_fill_value(value) # GH#45725 if isinstance(values, Categorical): # TODO: avoid special-casing diff --git a/pandas/tests/frame/methods/test_replace.py b/pandas/tests/frame/methods/test_replace.py index 001a50c3ce1b0..f92c779c85f03 100644 --- a/pandas/tests/frame/methods/test_replace.py +++ b/pandas/tests/frame/methods/test_replace.py @@ -661,6 +661,21 @@ def test_replace_simple_nested_dict_with_nonexistent_value(self): result = df.replace({"col": {-1: "-", 1: "a", 4: "b"}}) tm.assert_frame_equal(expected, result) + def test_replace_numpy_nan(self, nulls_fixture): + # GH#45725 ensure numpy.nan can be replaced with all other null types + to_replace = np.nan + value = nulls_fixture + dtype = object + df = DataFrame({"A": [to_replace]}, dtype=dtype) + expected = DataFrame({"A": [value]}, dtype=dtype) + + result = df.replace({to_replace: value}).astype(dtype=dtype) + tm.assert_frame_equal(result, expected) + + # same thing but different calling convention + result = df.replace(to_replace, value).astype(dtype=dtype) + tm.assert_frame_equal(result, expected) + def test_replace_value_is_none(self, datetime_frame): orig_value = datetime_frame.iloc[0, 0] orig2 = datetime_frame.iloc[1, 0] diff --git a/pandas/tests/series/methods/test_replace.py b/pandas/tests/series/methods/test_replace.py index 6a8dacfda5e78..c852898a217a1 100644 --- a/pandas/tests/series/methods/test_replace.py +++ b/pandas/tests/series/methods/test_replace.py @@ -36,6 +36,23 @@ def test_replace_explicit_none(self): assert expected.iloc[-1] is None tm.assert_series_equal(result, expected) + def test_replace_numpy_nan(self, nulls_fixture): + # GH#45725 ensure numpy.nan can be replaced with all other null types + to_replace = np.nan + value = nulls_fixture + dtype = object + ser = pd.Series([to_replace], dtype=dtype) + expected = pd.Series([value], dtype=dtype) + + result = ser.replace({to_replace: value}).astype(dtype=dtype) + tm.assert_series_equal(result, expected) + assert result.dtype == dtype + + # same thing but different calling convention + result = ser.replace(to_replace, value).astype(dtype=dtype) + tm.assert_series_equal(result, expected) + assert result.dtype == dtype + def test_replace_noop_doesnt_downcast(self): # GH#44498 ser = pd.Series([None, None, pd.Timestamp("2021-12-16 17:31")], dtype=object)