diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 9ea0ff323a33d..1b3e4864843f3 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -2734,7 +2734,7 @@ def _union(self, other, sort): stacklevel=3, ) - return self._shallow_copy(result) + return result @final def _wrap_setop_result(self, other, result): @@ -2742,6 +2742,8 @@ def _wrap_setop_result(self, other, result): result, np.ndarray ): result = type(self._data)._simple_new(result, dtype=self.dtype) + elif is_categorical_dtype(self.dtype) and isinstance(result, np.ndarray): + result = Categorical(result, dtype=self.dtype) name = get_op_result_name(self, other) if isinstance(result, Index): diff --git a/pandas/core/indexes/category.py b/pandas/core/indexes/category.py index d11d4952ff1c7..2cd18c99fe727 100644 --- a/pandas/core/indexes/category.py +++ b/pandas/core/indexes/category.py @@ -1,4 +1,4 @@ -from typing import Any, List +from typing import Any, List, Optional import warnings import numpy as np @@ -227,10 +227,15 @@ def _simple_new(cls, values: Categorical, name: Label = None): # -------------------------------------------------------------------- @doc(Index._shallow_copy) - def _shallow_copy(self, values=None, name: Label = no_default): + def _shallow_copy( + self, values: Optional[Categorical] = None, name: Label = no_default + ): name = self.name if name is no_default else name if values is not None: + # In tests we only get here with Categorical objects that + # have matching .ordered, and values.categories a subset of + # our own. However we do _not_ have a dtype match in general. values = Categorical(values, dtype=self.dtype) return super()._shallow_copy(values=values, name=name) diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py index 88383cb7bbb6a..2983b4b746dcd 100644 --- a/pandas/core/indexes/datetimelike.py +++ b/pandas/core/indexes/datetimelike.py @@ -765,11 +765,7 @@ def intersection(self, other, sort=False): start = right[0] if end < start: - # pandas\core\indexes\datetimelike.py:758: error: Unexpected - # keyword argument "freq" for "DatetimeTimedeltaMixin" [call-arg] - result = type(self)( - data=[], dtype=self.dtype, freq=self.freq # type: ignore[call-arg] - ) + result = self[:0] else: lslice = slice(*left.slice_locs(start, end)) left_chunk = left._values[lslice] diff --git a/pandas/core/indexes/range.py b/pandas/core/indexes/range.py index 4b8207331838e..8e12f84895361 100644 --- a/pandas/core/indexes/range.py +++ b/pandas/core/indexes/range.py @@ -29,7 +29,7 @@ from pandas.core.construction import extract_array import pandas.core.indexes.base as ibase from pandas.core.indexes.base import _index_shared_docs, maybe_extract_name -from pandas.core.indexes.numeric import Int64Index +from pandas.core.indexes.numeric import Float64Index, Int64Index from pandas.core.ops.common import unpack_zerodim_and_defer _empty_range = range(0) @@ -397,6 +397,8 @@ def _shallow_copy(self, values=None, name: Label = no_default): name = self.name if name is no_default else name if values is not None: + if values.dtype.kind == "f": + return Float64Index(values, name=name) return Int64Index._simple_new(values, name=name) result = self._simple_new(self._range, name=name) diff --git a/pandas/tests/indexes/base_class/test_setops.py b/pandas/tests/indexes/base_class/test_setops.py index 94c6d2ad6dc95..b571ff7f63f58 100644 --- a/pandas/tests/indexes/base_class/test_setops.py +++ b/pandas/tests/indexes/base_class/test_setops.py @@ -31,7 +31,7 @@ def test_setops_preserve_object_dtype(self): result = idx._union(idx[1:], sort=None) expected = idx - tm.assert_index_equal(result, expected) + tm.assert_numpy_array_equal(result, expected.values) result = idx.union(idx[1:], sort=None) tm.assert_index_equal(result, expected) @@ -39,7 +39,7 @@ def test_setops_preserve_object_dtype(self): # if other is not monotonic increasing, _union goes through # a different route result = idx._union(idx[1:][::-1], sort=None) - tm.assert_index_equal(result, expected) + tm.assert_numpy_array_equal(result, expected.values) result = idx.union(idx[1:][::-1], sort=None) tm.assert_index_equal(result, expected)