diff --git a/doc/source/whatsnew/v1.2.0.rst b/doc/source/whatsnew/v1.2.0.rst index 1286577748afa..907cc246163c8 100644 --- a/doc/source/whatsnew/v1.2.0.rst +++ b/doc/source/whatsnew/v1.2.0.rst @@ -339,6 +339,7 @@ Groupby/resample/rolling - Bug in :meth:`DataFrameGroupby.tshift` failing to raise ``ValueError`` when a frequency cannot be inferred for the index of a group (:issue:`35937`) - Bug in :meth:`DataFrame.groupby` does not always maintain column index name for ``any``, ``all``, ``bfill``, ``ffill``, ``shift`` (:issue:`29764`) - Bug in :meth:`DataFrameGroupBy.apply` raising error with ``np.nan`` group(s) when ``dropna=False`` (:issue:`35889`) +- Bug where :meth:`DataFrame.replace` and :meth:`Series.replace` would fail when replacement value was of a different dtype but equal to values in the original object (:issue:`34871`). - Reshaping diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index eb5b887c8b0cb..abcdfcc4840a6 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -714,9 +714,13 @@ def replace( # retry if not self._can_hold_element(to_replace): if not isinstance(to_replace, list): - if inplace: - return [self] - return [self.copy()] + return self.astype(object).replace( + to_replace=to_replace, + value=value, + inplace=inplace, + regex=regex, + convert=convert, + ) to_replace = [x for x in to_replace if self._can_hold_element(x)] if not len(to_replace): diff --git a/pandas/tests/frame/methods/test_replace.py b/pandas/tests/frame/methods/test_replace.py index a77753ed9f9d0..c028bbfe82894 100644 --- a/pandas/tests/frame/methods/test_replace.py +++ b/pandas/tests/frame/methods/test_replace.py @@ -1492,6 +1492,13 @@ def test_replace_with_duplicate_columns(self, replacement): tm.assert_frame_equal(result, expected) + def test_replace_equal_value_different_dtype(self): + # https://github.com/pandas-dev/pandas/issues/34871 + df = pd.DataFrame([1, 2, 3]) + result = df.replace(1.0, 0) + expected = pd.DataFrame([0, 2, 3]) + tm.assert_frame_equal(result, expected) + @pytest.mark.xfail( reason="replace() changes dtype from period to object, see GH34871", strict=True ) diff --git a/pandas/tests/series/methods/test_replace.py b/pandas/tests/series/methods/test_replace.py index e255d46e81851..8a6b51ef61875 100644 --- a/pandas/tests/series/methods/test_replace.py +++ b/pandas/tests/series/methods/test_replace.py @@ -442,6 +442,13 @@ def test_replace_extension_other(self): ser = pd.Series(pd.array([1, 2, 3], dtype="Int64")) ser.replace("", "") # no exception + def test_replace_equal_value_different_dtype(self): + # https://github.com/pandas-dev/pandas/issues/34871 + ser = pd.Series([1, 2, 3]) + result = ser.replace(1.0, 0) + expected = pd.Series([0, 2, 3]) + tm.assert_series_equal(result, expected) + def test_replace_with_compiled_regex(self): # https://github.com/pandas-dev/pandas/issues/35680 s = pd.Series(["a", "b", "c"])