From ef4ab0f721621ddb76abfb4fb45c72db92307af8 Mon Sep 17 00:00:00 2001 From: Simon Hawkins Date: Thu, 14 May 2020 13:26:40 +0100 Subject: [PATCH] Backport PR #34048 on branch 1.0.x (Bug in DataFrame.replace casts columns to ``object`` dtype if items in ``to_replace`` not in values) (#34115) --- doc/source/whatsnew/v1.0.4.rst | 1 + pandas/core/internals/blocks.py | 5 ----- pandas/tests/frame/methods/test_replace.py | 8 ++++++++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/doc/source/whatsnew/v1.0.4.rst b/doc/source/whatsnew/v1.0.4.rst index 714bcfb8720db..2d73cbd72c67a 100644 --- a/doc/source/whatsnew/v1.0.4.rst +++ b/doc/source/whatsnew/v1.0.4.rst @@ -23,6 +23,7 @@ Fixed regressions - Bug where an ordered :class:`Categorical` containing only ``NaN`` values would raise rather than returning ``NaN`` when taking the minimum or maximum (:issue:`33450`) - Bug in :meth:`DataFrameGroupBy.agg` with dictionary input losing ``ExtensionArray`` dtypes (:issue:`32194`) - Fix to preserve the ability to index with the "nearest" method with xarray's CFTimeIndex, an :class:`Index` subclass (`pydata/xarray#3751 `_, :issue:`32905`). +- Bug in :meth:`DataFrame.replace` casts columns to ``object`` dtype if items in ``to_replace`` not in values (:issue:`32988`) - .. _whatsnew_104.bug_fixes: diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 33a5d6443aa7c..5172b4a7097f3 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -765,11 +765,6 @@ def replace( filtered_out = ~self.mgr_locs.isin(filter) mask[filtered_out.nonzero()[0]] = False - if not mask.any(): - if inplace: - return [self] - return [self.copy()] - try: blocks = self.putmask(mask, value, inplace=inplace) # Note: it is _not_ the case that self._can_hold_element(value) diff --git a/pandas/tests/frame/methods/test_replace.py b/pandas/tests/frame/methods/test_replace.py index 92b74c4409d7d..97ef36bb8b599 100644 --- a/pandas/tests/frame/methods/test_replace.py +++ b/pandas/tests/frame/methods/test_replace.py @@ -1363,3 +1363,11 @@ def test_replace_after_convert_dtypes(self): result = df.replace(1, 10) expected = pd.DataFrame({"grp": [10, 2, 3, 4, 5]}, dtype="Int64") tm.assert_frame_equal(result, expected) + + @pytest.mark.parametrize("dtype", ["float", "float64", "int64", "Int64", "boolean"]) + @pytest.mark.parametrize("value", [np.nan, pd.NA]) + def test_replace_no_replacement_dtypes(self, dtype, value): + # https://github.com/pandas-dev/pandas/issues/32988 + df = pd.DataFrame(np.eye(2), dtype=dtype) + result = df.replace(to_replace=[None, -np.inf, np.inf], value=value) + tm.assert_frame_equal(result, df)