From d1252c81c18b93fc9600d00b425c42a28979aa49 Mon Sep 17 00:00:00 2001 From: Johannes Mueller Date: Fri, 28 Jan 2022 20:00:33 +0100 Subject: [PATCH] Backport PR #45662: BUG: Fix joining overlapping IntervalIndex objects (GH-45661) --- doc/source/whatsnew/v1.4.1.rst | 1 + pandas/core/indexes/base.py | 4 +- pandas/tests/indexes/interval/test_join.py | 44 ++++++++++++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 pandas/tests/indexes/interval/test_join.py diff --git a/doc/source/whatsnew/v1.4.1.rst b/doc/source/whatsnew/v1.4.1.rst index d0a58a19df92f..23aefb783456d 100644 --- a/doc/source/whatsnew/v1.4.1.rst +++ b/doc/source/whatsnew/v1.4.1.rst @@ -18,6 +18,7 @@ Fixed regressions - Regression in :func:`.assert_frame_equal` not respecting ``check_flags=False`` (:issue:`45554`) - Regression in :meth:`Series.fillna` with ``downcast=False`` incorrectly downcasting ``object`` dtype (:issue:`45603`) - Regression in :meth:`DataFrame.loc.__setitem__` losing :class:`Index` name if :class:`DataFrame` was empty before (:issue:`45621`) +- Regression in :func:`join` with overlapping :class:`IntervalIndex` raising an ``InvalidIndexError`` (:issue:`45661`) - .. --------------------------------------------------------------------------- diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 480ec29c418b8..2abd649d00b78 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -4453,11 +4453,11 @@ def _join_via_get_indexer( if join_index is self: lindexer = None else: - lindexer = self.get_indexer(join_index) + lindexer = self.get_indexer_for(join_index) if join_index is other: rindexer = None else: - rindexer = other.get_indexer(join_index) + rindexer = other.get_indexer_for(join_index) return join_index, lindexer, rindexer @final diff --git a/pandas/tests/indexes/interval/test_join.py b/pandas/tests/indexes/interval/test_join.py new file mode 100644 index 0000000000000..2f42c530a6686 --- /dev/null +++ b/pandas/tests/indexes/interval/test_join.py @@ -0,0 +1,44 @@ +import pytest + +from pandas import ( + IntervalIndex, + MultiIndex, + RangeIndex, +) +import pandas._testing as tm + + +@pytest.fixture +def range_index(): + return RangeIndex(3, name="range_index") + + +@pytest.fixture +def interval_index(): + return IntervalIndex.from_tuples( + [(0.0, 1.0), (1.0, 2.0), (1.5, 2.5)], name="interval_index" + ) + + +def test_join_overlapping_in_mi_to_same_intervalindex(range_index, interval_index): + # GH-45661 + multi_index = MultiIndex.from_product([interval_index, range_index]) + result = multi_index.join(interval_index) + + tm.assert_index_equal(result, multi_index) + + +def test_join_overlapping_to_multiindex_with_same_interval(range_index, interval_index): + # GH-45661 + multi_index = MultiIndex.from_product([interval_index, range_index]) + result = interval_index.join(multi_index) + + tm.assert_index_equal(result, multi_index) + + +def test_join_overlapping_interval_to_another_intervalindex(interval_index): + # GH-45661 + flipped_interval_index = interval_index[::-1] + result = interval_index.join(flipped_interval_index) + + tm.assert_index_equal(result, interval_index)