diff --git a/doc/source/whatsnew/v2.3.2.rst b/doc/source/whatsnew/v2.3.2.rst deleted file mode 100644 index 53a8d28687518..0000000000000 --- a/doc/source/whatsnew/v2.3.2.rst +++ /dev/null @@ -1,34 +0,0 @@ -.. _whatsnew_232: - -What's new in 2.3.2 (August XX, 2025) -------------------------------------- - -These are the changes in pandas 2.3.2. See :ref:`release` for a full changelog -including other versions of pandas. - -{{ header }} - -.. --------------------------------------------------------------------------- -.. _whatsnew_232.string_fixes: - -Improvements and fixes for the StringDtype -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Most changes in this release are related to :class:`StringDtype` which will -become the default string dtype in pandas 3.0. See -:ref:`whatsnew_230.upcoming_changes` for more details. - -.. _whatsnew_232.string_fixes.bugs: - -Bug fixes -^^^^^^^^^ -- Fix :meth:`~DataFrame.to_json` with ``orient="table"`` to correctly use the - "string" type in the JSON Table Schema for :class:`StringDtype` columns - (:issue:`61889`) -- Boolean operations (``|``, ``&``, ``^``) with bool-dtype objects on the left and :class:`StringDtype` objects on the right now cast the string to bool, with a deprecation warning (:issue:`60234`) - -.. --------------------------------------------------------------------------- -.. _whatsnew_232.contributors: - -Contributors -~~~~~~~~~~~~ diff --git a/pandas/core/arrays/interval.py b/pandas/core/arrays/interval.py index 4bcbe2eedee47..2f235013895d0 100644 --- a/pandas/core/arrays/interval.py +++ b/pandas/core/arrays/interval.py @@ -1423,9 +1423,20 @@ def mid(self) -> Index: ) def overlaps(self, other): if isinstance(other, (IntervalArray, ABCIntervalIndex)): - raise NotImplementedError + if not isinstance(other, IntervalArray): + other = IntervalArray(other) + if len(self) != len(other): + raise ValueError("Both IntervalArrays must have the same length.") + if self.closed != other.closed: + raise ValueError( + "Both IntervalArrays must have the same 'closed' property." + ) + + op1 = le if (self.closed_left and other.closed_right) else lt + op2 = le if (other.closed_left and self.closed_right) else lt + return op1(self.left, other.right) & op2(other.left, self.right) if not isinstance(other, Interval): - msg = f"`other` must be Interval-like, got {type(other).__name__}" + msg = f" `other` must be Interval-like, got {type(other).__name__}" raise TypeError(msg) # equality is okay if both endpoints are closed (overlap at a point) diff --git a/pandas/tests/arrays/interval/test_interval.py b/pandas/tests/arrays/interval/test_interval.py index 8e13dcf25ceba..685d55486d562 100644 --- a/pandas/tests/arrays/interval/test_interval.py +++ b/pandas/tests/arrays/interval/test_interval.py @@ -229,3 +229,34 @@ def test_min_max(self, left_right_dtypes, index_or_series_or_array): res = arr_na.max(**kws) assert res == MAX assert type(res) == type(MAX) + + def test_intervalarray_overlaps_all_cases(self): + # Basic self-overlap + data = [(0, 1), (1, 3), (2, 4)] + arr = IntervalArray.from_tuples(data) + result = arr.overlaps(arr) + expected = np.array([True, True, True]) + tm.testing.assert_array_equal(result, expected) + + # Overlap with different intervals + arr2 = IntervalArray.from_tuples([(0.5, 1.5), (2, 2.5), (3, 5)]) + result2 = arr.overlaps(arr2) + expected2 = np.array([True, False, True]) + tm.testing.assert_array_equal(result2, expected2) + + # Length mismatch + arr_short = IntervalArray.from_tuples([(0, 1)]) + with pytest.raises(ValueError, match="same length"): + arr.overlaps(arr_short) + + # Closed property mismatch + arr_left = IntervalArray.from_tuples(data, closed="left") + arr_right = IntervalArray.from_tuples(data, closed="right") + with pytest.raises(ValueError, match="same 'closed' property"): + arr_left.overlaps(arr_right) + + # Overlap with scalar interval + interval = Interval(1, 2) + result3 = arr.overlaps(interval) + expected3 = np.array([False, True, False]) + tm.testing.assert_array_equal(result3, expected3)