diff --git a/doc/source/whatsnew/v1.2.0.rst b/doc/source/whatsnew/v1.2.0.rst index 94eb9a0b3fc58..cb4d04d4443e7 100644 --- a/doc/source/whatsnew/v1.2.0.rst +++ b/doc/source/whatsnew/v1.2.0.rst @@ -831,6 +831,7 @@ Other - Bug in :meth:`Index.difference` failing to set the correct name on the returned :class:`Index` in some corner cases (:issue:`38268`) - Bug in :meth:`Index.union` behaving differently depending on whether operand is an :class:`Index` or other list-like (:issue:`36384`) - Bug in :meth:`Index.intersection` with non-matching numeric dtypes casting to ``object`` dtype instead of minimal common dtype (:issue:`38122`) +- Bug in :meth:`IntervalIndex.intersection` returning an incorrectly-typed :class:`Index` when empty (:issue:`38282`) - Passing an array with 2 or more dimensions to the :class:`Series` constructor now raises the more specific ``ValueError`` rather than a bare ``Exception`` (:issue:`35744`) - Bug in ``dir`` where ``dir(obj)`` wouldn't show attributes defined on the instance for pandas objects (:issue:`37173`) - Bug in :meth:`Index.drop` raising ``InvalidIndexError`` when index has duplicates (:issue:`38051`) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index c0840d8e0d4b0..ba958b23e81af 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -2694,7 +2694,7 @@ def union(self, other, sort=None): """ self._validate_sort_keyword(sort) self._assert_can_do_setop(other) - other = ensure_index(other) + other, result_name = self._convert_can_do_setop(other) if not self._can_union_without_object_cast(other): return self._union_incompatible_dtypes(other, sort=sort) diff --git a/pandas/core/indexes/interval.py b/pandas/core/indexes/interval.py index 3036e944d1e51..2f86d9c20bfe8 100644 --- a/pandas/core/indexes/interval.py +++ b/pandas/core/indexes/interval.py @@ -1060,6 +1060,10 @@ def _intersection_non_unique(self, other: "IntervalIndex") -> "IntervalIndex": def _setop(op_name: str, sort=None): def func(self, other, sort=sort): + # At this point we are assured + # isinstance(other, IntervalIndex) + # other.closed == self.closed + result = getattr(self._multiindex, op_name)(other._multiindex, sort=sort) result_name = get_op_result_name(self, other) @@ -1074,7 +1078,7 @@ def func(self, other, sort=sort): func.__name__ = op_name return setop_check(func) - union = _setop("union") + _union = _setop("union") difference = _setop("difference") symmetric_difference = _setop("symmetric_difference") diff --git a/pandas/core/indexes/multi.py b/pandas/core/indexes/multi.py index 911bbc44bb599..fd47c23b7c92b 100644 --- a/pandas/core/indexes/multi.py +++ b/pandas/core/indexes/multi.py @@ -3569,6 +3569,11 @@ def union(self, other, sort=None): if len(other) == 0 or self.equals(other): return self.rename(result_names) + return self._union(other, sort=sort) + + def _union(self, other, sort): + other, result_names = self._convert_can_do_setop(other) + # TODO: Index.union returns other when `len(self)` is 0. if not is_object_dtype(other.dtype): diff --git a/pandas/tests/indexes/interval/test_setops.py b/pandas/tests/indexes/interval/test_setops.py index 0b94d70367b4d..0ef833bb93ded 100644 --- a/pandas/tests/indexes/interval/test_setops.py +++ b/pandas/tests/indexes/interval/test_setops.py @@ -32,15 +32,17 @@ def test_union(self, closed, sort): tm.assert_index_equal(index.union(index, sort=sort), index) tm.assert_index_equal(index.union(index[:1], sort=sort), index) + def test_union_empty_result(self, closed, sort): # GH 19101: empty result, same dtype index = empty_index(dtype="int64", closed=closed) result = index.union(index, sort=sort) tm.assert_index_equal(result, index) - # GH 19101: empty result, different dtypes + # GH 19101: empty result, different dtypes -> common dtype is object other = empty_index(dtype="float64", closed=closed) result = index.union(other, sort=sort) - tm.assert_index_equal(result, index) + expected = Index([], dtype=object) + tm.assert_index_equal(result, expected) def test_intersection(self, closed, sort): index = monotonic_index(0, 11, closed=closed)