diff --git a/doc/source/whatsnew/v1.4.4.rst b/doc/source/whatsnew/v1.4.4.rst index 96e4ad4321c60..0393879a766a5 100644 --- a/doc/source/whatsnew/v1.4.4.rst +++ b/doc/source/whatsnew/v1.4.4.rst @@ -16,6 +16,7 @@ Fixed regressions ~~~~~~~~~~~~~~~~~ - Fixed regression in taking NULL :class:`objects` from a :class:`DataFrame` causing a segmentation violation. These NULL values are created by :meth:`numpy.empty_like` (:issue:`46848`) - Fixed regression in :func:`concat` materializing :class:`Index` during sorting even if :class:`Index` was already sorted (:issue:`47501`) +- Fixed regression in :func:`cut` using a ``datetime64`` IntervalIndex as bins (:issue:`46218`) - Fixed regression in :meth:`DataFrame.loc` not updating the cache correctly after values were set (:issue:`47867`) - Fixed regression in :meth:`DataFrame.loc` not aligning index in some cases when setting a :class:`DataFrame` (:issue:`47578`) - Fixed regression in setting ``None`` or non-string value into a ``string``-dtype Series using a mask (:issue:`47628`) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 816260c8a6d2d..1e8ba81c877ac 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -3987,8 +3987,14 @@ def _should_partial_index(self, target: Index) -> bool: Should we attempt partial-matching indexing? """ if is_interval_dtype(self.dtype): + if is_interval_dtype(target.dtype): + return False + # See https://github.com/pandas-dev/pandas/issues/47772 the commented + # out code can be restored (instead of hardcoding `return True`) + # once that issue if fixed # "Index" has no attribute "left" - return self.left._should_compare(target) # type: ignore[attr-defined] + # return self.left._should_compare(target) # type: ignore[attr-defined] + return True return False @final diff --git a/pandas/tests/indexes/interval/test_indexing.py b/pandas/tests/indexes/interval/test_indexing.py index 9b4afcc9c00b8..4653981a1285d 100644 --- a/pandas/tests/indexes/interval/test_indexing.py +++ b/pandas/tests/indexes/interval/test_indexing.py @@ -8,6 +8,7 @@ from pandas import ( NA, CategoricalIndex, + DatetimeIndex, Index, Interval, IntervalIndex, @@ -302,6 +303,20 @@ def test_get_indexer_categorical_with_nans(self): expected = np.array([0, 1, 2, 3, 4, 0, 1, 2, 3, 4], dtype=np.intp) tm.assert_numpy_array_equal(result, expected) + def test_get_indexer_datetime(self): + ii = IntervalIndex.from_breaks(date_range("2018-01-01", periods=4)) + result = ii.get_indexer(DatetimeIndex(["2018-01-02"])) + expected = np.array([0], dtype=np.intp) + tm.assert_numpy_array_equal(result, expected) + + result = ii.get_indexer(DatetimeIndex(["2018-01-02"]).astype(str)) + tm.assert_numpy_array_equal(result, expected) + + # TODO this should probably be deprecated? + # https://github.com/pandas-dev/pandas/issues/47772 + result = ii.get_indexer(DatetimeIndex(["2018-01-02"]).asi8) + tm.assert_numpy_array_equal(result, expected) + @pytest.mark.parametrize( "tuples, closed", [ diff --git a/pandas/tests/reshape/test_cut.py b/pandas/tests/reshape/test_cut.py index 1425686f027e4..3b9ab6a83a575 100644 --- a/pandas/tests/reshape/test_cut.py +++ b/pandas/tests/reshape/test_cut.py @@ -14,6 +14,7 @@ Timestamp, cut, date_range, + interval_range, isna, qcut, timedelta_range, @@ -734,3 +735,12 @@ def test_cut_with_timestamp_tuple_labels(): expected = Categorical.from_codes([0, 1, 2], labels, ordered=True) tm.assert_categorical_equal(result, expected) + + +def test_cut_bins_datetime_intervalindex(): + # https://github.com/pandas-dev/pandas/issues/46218 + bins = interval_range(Timestamp("2022-02-25"), Timestamp("2022-02-27"), freq="1D") + # passing Series instead of list is important to trigger bug + result = cut(Series([Timestamp("2022-02-26")]), bins=bins) + expected = Categorical.from_codes([0], bins, ordered=True) + tm.assert_categorical_equal(result.array, expected)