From 1311095536bf97a5347565a014ae04ae3c3ce295 Mon Sep 17 00:00:00 2001 From: Brock Date: Wed, 2 Feb 2022 19:40:37 -0800 Subject: [PATCH 1/2] BUG: Series[Interval].fillna(mismatched) coerce instead of raise --- doc/source/whatsnew/v1.5.0.rst | 1 + pandas/core/internals/blocks.py | 5 ----- pandas/tests/indexing/test_coercion.py | 24 ++++++++++++++++++++++++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/doc/source/whatsnew/v1.5.0.rst b/doc/source/whatsnew/v1.5.0.rst index 8bb924f4003a2..e39d17e095d0e 100644 --- a/doc/source/whatsnew/v1.5.0.rst +++ b/doc/source/whatsnew/v1.5.0.rst @@ -282,6 +282,7 @@ Indexing Missing ^^^^^^^ - Bug in :meth:`Series.fillna` and :meth:`DataFrame.fillna` with ``downcast`` keyword not being respected in some cases where there are no NA values present (:issue:`45423`) +- Bug in :meth:`Series.fillna` and :meth:`DataFrame.fillna` with :class:`IntervalDtype` and incompatible value raising instead of casting to a common (usually object) dtype (:issue:`??`) - Bug in :meth:`DataFrame.interpolate` with object-dtype column not returning a copy with ``inplace=False`` (:issue:`45791`) - diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index e01a31c0a20af..41b749b5dbb4f 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -1465,11 +1465,6 @@ def fillna( # Discussion about what we want to support in the general # case GH#39584 blk = self.coerce_to_target_dtype(value) - if blk.dtype == _dtype_obj: - # For now at least, only support casting e.g. - # Interval[int64]->Interval[float64], - raise - # Never actually reached, but *could* be possible pending GH#45412 return blk.fillna(value, limit, inplace, downcast) elif isinstance(self, NDArrayBackedExtensionBlock): diff --git a/pandas/tests/indexing/test_coercion.py b/pandas/tests/indexing/test_coercion.py index 5ef079270479f..ab9eef218c0da 100644 --- a/pandas/tests/indexing/test_coercion.py +++ b/pandas/tests/indexing/test_coercion.py @@ -709,6 +709,30 @@ def test_fillna_datetime64tz(self, index_or_series, fill_val, fill_dtype): with tm.assert_produces_warning(warn, match="mismatched timezone"): self._assert_fillna_conversion(obj, fill_val, exp, fill_dtype) + @pytest.mark.parametrize( + "fill_val", + [ + 1, + 1.1, + 1 + 1j, + True, + pd.Interval(1, 2, closed="left"), + pd.Timestamp("2012-01-01", tz="US/Eastern"), + pd.Timestamp("2012-01-01"), + pd.Timedelta(days=1), + pd.Period("2016-01-01", "D"), + ], + ) + def test_fillna_interval(self, index_or_series, fill_val): + ii = pd.interval_range(1.0, 5.0, closed="right").insert(1, np.nan) + assert isinstance(ii.dtype, pd.IntervalDtype) + obj = index_or_series(ii) + + exp = index_or_series([ii[0], fill_val, ii[2], ii[3], ii[4]], dtype=object) + + fill_dtype = object + self._assert_fillna_conversion(obj, fill_val, exp, fill_dtype) + @pytest.mark.xfail(reason="Test not implemented") def test_fillna_series_int64(self): raise NotImplementedError From 975c697e4388b0a0a05f8d1a485462e64ab714b6 Mon Sep 17 00:00:00 2001 From: Brock Date: Thu, 3 Feb 2022 08:55:57 -0800 Subject: [PATCH 2/2] mypy pandas --- pandas/core/internals/blocks.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index 41b749b5dbb4f..532f65b70e45a 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -1139,7 +1139,11 @@ def shift(self, periods: int, axis: int = 0, fill_value: Any = None) -> list[Blo fill_value = self._standardize_fill_value(fill_value) try: - casted = np_can_hold_element(self.dtype, fill_value) + # error: Argument 1 to "np_can_hold_element" has incompatible type + # "Union[dtype[Any], ExtensionDtype]"; expected "dtype[Any]" + casted = np_can_hold_element( + self.dtype, fill_value # type: ignore[arg-type] + ) except LossySetitemError: nb = self.coerce_to_target_dtype(fill_value) return nb.shift(periods, axis=axis, fill_value=fill_value)