diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 1d572dbfd5386..8923faf444953 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -480,7 +480,15 @@ def convert( return [self.copy()] if copy else [self] if self.ndim != 1 and self.shape[0] != 1: - return self.split_and_operate(Block.convert, copy=copy, using_cow=using_cow) + blocks = self.split_and_operate( + Block.convert, copy=copy, using_cow=using_cow + ) + if all(blk.dtype.kind == "O" for blk in blocks): + # Avoid fragmenting the block if convert is a no-op + if using_cow: + return [self.copy(deep=False)] + return [self.copy()] if copy else [self] + return blocks values = self.values if values.ndim == 2: diff --git a/pandas/tests/frame/methods/test_replace.py b/pandas/tests/frame/methods/test_replace.py index 9256df72cdf7b..1846ac24e9cc5 100644 --- a/pandas/tests/frame/methods/test_replace.py +++ b/pandas/tests/frame/methods/test_replace.py @@ -1592,3 +1592,10 @@ def test_replace_categorical_no_replacement(self): result = df.replace(to_replace=[".", "def"], value=["_", None]) tm.assert_frame_equal(result, expected) + + def test_replace_object_splitting(self): + # GH#53977 + df = DataFrame({"a": ["a"], "b": "b"}) + assert len(df._mgr.blocks) == 1 + df.replace(to_replace=r"^\s*$", value="", inplace=True, regex=True) + assert len(df._mgr.blocks) == 1