diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index e4dcffae45f67..196ce6dbafb4f 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -711,13 +711,24 @@ def replace( # try again with a compatible block block = self.astype(object) - return block.replace( + block_replaced = block.replace( to_replace=to_replace, value=value, inplace=inplace, regex=regex, convert=convert, ) + blocks_converted = [] + for ls_elem in block_replaced: + # If a replace was executed block_replaced is list of lists, + # if no replace was necessary block_replaced is only a list + if is_list_like(ls_elem): + blocks_converted.extend( + [sub_block.convert() for sub_block in ls_elem] + ) + else: + blocks_converted.extend([ls_elem.convert()]) + return blocks_converted values = self.values if lib.is_scalar(to_replace) and isinstance(values, np.ndarray): diff --git a/pandas/tests/frame/methods/test_replace.py b/pandas/tests/frame/methods/test_replace.py index a9fb686d5bc50..18648df5b8146 100644 --- a/pandas/tests/frame/methods/test_replace.py +++ b/pandas/tests/frame/methods/test_replace.py @@ -22,6 +22,20 @@ def mix_abc() -> Dict[str, List[Union[float, str]]]: class TestDataFrameReplace: + def test_replace_without_type_cast(self): + # PH: 32988: Fix unwanted type casting while replacing + result = pd.DataFrame(np.eye(2)).replace( + to_replace=[None, -np.inf, np.inf], value=pd.NA + ) + tm.assert_frame_equal(result, pd.DataFrame(np.eye(2))) + + result = pd.DataFrame(np.eye(2)).replace( + to_replace=[None, -np.inf, np.inf, 1.0], value=pd.NA + ) + + expected = pd.DataFrame({0: [np.nan, 0.0], 1: [0.0, np.nan]}) + tm.assert_frame_equal(result, expected) + def test_replace_inplace(self, datetime_frame, float_string_frame): datetime_frame["A"][:5] = np.nan datetime_frame["A"][-5:] = np.nan