diff --git a/doc/source/whatsnew/v1.2.0.rst b/doc/source/whatsnew/v1.2.0.rst index 28f7df98cb86b..d56f3c978384c 100644 --- a/doc/source/whatsnew/v1.2.0.rst +++ b/doc/source/whatsnew/v1.2.0.rst @@ -562,6 +562,8 @@ Strings Interval ^^^^^^^^ + +- Bug in :meth:`DataFrame.replace` and :meth:`Series.replace` where :class:`Interval` dtypes would be converted to object dtypes (:issue:`34871`) - Bug in :meth:`IntervalIndex.take` with negative indices and ``fill_value=None`` (:issue:`37330`) - - @@ -626,6 +628,11 @@ I/O - :meth:`to_excel` and :meth:`to_markdown` support writing to fsspec URLs such as S3 and Google Cloud Storage (:issue:`33987`) - Bug in :meth:`read_fw` was not skipping blank lines (even with ``skip_blank_lines=True``) (:issue:`37758`) +Period +^^^^^^ + +- Bug in :meth:`DataFrame.replace` and :meth:`Series.replace` where :class:`Period` dtypes would be converted to object dtypes (:issue:`34871`) + Plotting ^^^^^^^^ diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 967e218078a28..f1759fbda0b8c 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -2041,6 +2041,16 @@ class ObjectValuesExtensionBlock(ExtensionBlock): def external_values(self): return self.values.astype(object) + def _can_hold_element(self, element: Any) -> bool: + if is_valid_nat_for_dtype(element, self.dtype): + return True + if isinstance(element, list) and len(element) == 0: + return True + tipo = maybe_infer_dtype_type(element) + if tipo is not None: + return issubclass(tipo.type, self.dtype.type) + return isinstance(element, self.dtype.type) + class NumericBlock(Block): __slots__ = () diff --git a/pandas/tests/frame/methods/test_replace.py b/pandas/tests/frame/methods/test_replace.py index 8f3dcc96ddc3d..8e59dd959ab57 100644 --- a/pandas/tests/frame/methods/test_replace.py +++ b/pandas/tests/frame/methods/test_replace.py @@ -1523,12 +1523,10 @@ def test_replace_with_duplicate_columns(self, replacement): tm.assert_frame_equal(result, expected) - def test_replace_period_ignore_float(self, frame_or_series): - """ - Regression test for GH#34871: if df.replace(1.0, 0.0) is called on a df - with a Period column the old, faulty behavior is to raise TypeError. - """ - obj = DataFrame({"Per": [pd.Period("2020-01")] * 3}) + @pytest.mark.parametrize("value", [pd.Period("2020-01"), pd.Interval(0, 5)]) + def test_replace_ea_ignore_float(self, frame_or_series, value): + # GH#34871 + obj = DataFrame({"Per": [value] * 3}) if frame_or_series is not DataFrame: obj = obj["Per"]