diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 9e00278f85cbc..999ef0d7ac68c 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -90,7 +90,6 @@ ensure_platform_int, is_bool_dtype, is_categorical_dtype, - is_complex_dtype, is_dtype_equal, is_ea_or_datetimelike_dtype, is_extension_array_dtype, @@ -107,7 +106,6 @@ is_scalar, is_signed_integer_dtype, is_string_dtype, - is_unsigned_integer_dtype, needs_i8_conversion, pandas_dtype, validate_all_hashable, @@ -125,7 +123,6 @@ ABCDatetimeIndex, ABCMultiIndex, ABCPeriodIndex, - ABCRangeIndex, ABCSeries, ABCTimedeltaIndex, ) @@ -392,11 +389,6 @@ def _outer_indexer( _attributes: list[str] = ["name"] _can_hold_strings: bool = True - # Whether this index is a NumericIndex, but not a Int64Index, Float64Index, - # UInt64Index or RangeIndex. Needed for backwards compat. Remove this attribute and - # associated code in pandas 2.0. - _is_backward_compat_public_numeric_index: bool = False - @property def _engine_type( self, @@ -446,13 +438,6 @@ def __new__( elif is_ea_or_datetimelike_dtype(data_dtype): pass - # index-like - elif ( - isinstance(data, Index) - and data._is_backward_compat_public_numeric_index - and dtype is None - ): - return data._constructor(data, name=name, copy=copy) elif isinstance(data, (np.ndarray, Index, ABCSeries)): if isinstance(data, ABCMultiIndex): @@ -981,34 +966,6 @@ def astype(self, dtype, copy: bool = True): new_values = astype_array(values, dtype=dtype, copy=copy) # pass copy=False because any copying will be done in the astype above - if not self._is_backward_compat_public_numeric_index and not isinstance( - self, ABCRangeIndex - ): - # this block is needed so e.g. Int64Index.astype("int32") returns - # Int64Index and not a NumericIndex with dtype int32. - # When Int64Index etc. are removed from the code base, removed this also. - if ( - isinstance(dtype, np.dtype) - and is_numeric_dtype(dtype) - and not is_complex_dtype(dtype) - ): - from pandas.core.api import ( - Float64Index, - Int64Index, - UInt64Index, - ) - - klass: type[Index] - if is_signed_integer_dtype(dtype): - klass = Int64Index - elif is_unsigned_integer_dtype(dtype): - klass = UInt64Index - elif is_float_dtype(dtype): - klass = Float64Index - else: - klass = Index - return klass(new_values, name=self.name, dtype=dtype, copy=False) - return Index(new_values, name=self.name, dtype=new_values.dtype, copy=False) _index_shared_docs[ @@ -5059,10 +5016,6 @@ def _concat(self, to_concat: list[Index], name: Hashable) -> Index: result = concat_compat(to_concat_vals) - is_numeric = result.dtype.kind in ["i", "u", "f"] - if self._is_backward_compat_public_numeric_index and is_numeric: - return type(self)._simple_new(result, name=name) - return Index._with_infer(result, name=name) def putmask(self, mask, value) -> Index: @@ -6460,12 +6413,7 @@ def insert(self, loc: int, item) -> Index: loc = loc if loc >= 0 else loc - 1 new_values[loc] = item - if self._typ == "numericindex": - # Use self._constructor instead of Index to retain NumericIndex GH#43921 - # TODO(2.0) can use Index instead of self._constructor - return self._constructor(new_values, name=self.name) - else: - return Index._with_infer(new_values, name=self.name) + return Index._with_infer(new_values, name=self.name) def drop( self, diff --git a/pandas/core/indexes/category.py b/pandas/core/indexes/category.py index 6c172a2034524..ff24f97106c51 100644 --- a/pandas/core/indexes/category.py +++ b/pandas/core/indexes/category.py @@ -21,7 +21,6 @@ from pandas.core.dtypes.common import ( is_categorical_dtype, is_scalar, - pandas_dtype, ) from pandas.core.dtypes.missing import ( is_valid_na_for_dtype, @@ -274,30 +273,6 @@ def _is_dtype_compat(self, other) -> Categorical: return other - @doc(Index.astype) - def astype(self, dtype: Dtype, copy: bool = True) -> Index: - from pandas.core.api import NumericIndex - - dtype = pandas_dtype(dtype) - - categories = self.categories - # the super method always returns Int64Index, UInt64Index and Float64Index - # but if the categories are a NumericIndex with dtype float32, we want to - # return an index with the same dtype as self.categories. - if categories._is_backward_compat_public_numeric_index: - assert isinstance(categories, NumericIndex) # mypy complaint fix - try: - categories._validate_dtype(dtype) - except ValueError: - pass - else: - new_values = self._data.astype(dtype, copy=copy) - # pass copy=False because any copying has been done in the - # _data.astype call above - return categories._constructor(new_values, name=self.name, copy=False) - - return super().astype(dtype, copy=copy) - def equals(self, other: object) -> bool: """ Determine if two CategoricalIndex objects contain the same elements. diff --git a/pandas/core/indexes/numeric.py b/pandas/core/indexes/numeric.py index af3ff54bb9e2b..3ea7b30f7e9f1 100644 --- a/pandas/core/indexes/numeric.py +++ b/pandas/core/indexes/numeric.py @@ -87,7 +87,6 @@ class NumericIndex(Index): "numeric type", ) _can_hold_strings = False - _is_backward_compat_public_numeric_index: bool = True _engine_types: dict[np.dtype, type[libindex.IndexEngine]] = { np.dtype(np.int8): libindex.Int8Engine, @@ -214,12 +213,7 @@ def _ensure_dtype(cls, dtype: Dtype | None) -> np.dtype | None: # float16 not supported (no indexing engine) raise NotImplementedError("float16 indexes are not supported") - if cls._is_backward_compat_public_numeric_index: - # dtype for NumericIndex - return dtype - else: - # dtype for Int64Index, UInt64Index etc. Needed for backwards compat. - return cls._default_dtype + return dtype # ---------------------------------------------------------------- # Indexing Methods @@ -415,7 +409,6 @@ class Float64Index(NumericIndex): _typ = "float64index" _default_dtype = np.dtype(np.float64) _dtype_validation_metadata = (is_float_dtype, "float") - _is_backward_compat_public_numeric_index: bool = False @property def _engine_type(self) -> type[libindex.Float64Engine]: diff --git a/pandas/core/indexes/range.py b/pandas/core/indexes/range.py index e17a0d070be6a..73e4a51ca3e7c 100644 --- a/pandas/core/indexes/range.py +++ b/pandas/core/indexes/range.py @@ -103,7 +103,6 @@ class RangeIndex(NumericIndex): _typ = "rangeindex" _dtype_validation_metadata = (is_signed_integer_dtype, "signed integer") _range: range - _is_backward_compat_public_numeric_index: bool = False @property def _engine_type(self) -> type[libindex.Int64Engine]: diff --git a/pandas/tests/base/test_unique.py b/pandas/tests/base/test_unique.py index b1b0479f397b1..624d3d68d37fd 100644 --- a/pandas/tests/base/test_unique.py +++ b/pandas/tests/base/test_unique.py @@ -5,7 +5,6 @@ import pandas as pd import pandas._testing as tm -from pandas.core.api import NumericIndex from pandas.tests.base.common import allow_na_ops @@ -20,9 +19,6 @@ def test_unique(index_or_series_obj): expected = pd.MultiIndex.from_tuples(unique_values) expected.names = obj.names tm.assert_index_equal(result, expected, exact=True) - elif isinstance(obj, pd.Index) and obj._is_backward_compat_public_numeric_index: - expected = NumericIndex(unique_values, dtype=obj.dtype) - tm.assert_index_equal(result, expected, exact=True) elif isinstance(obj, pd.Index): expected = pd.Index(unique_values, dtype=obj.dtype) if is_datetime64tz_dtype(obj.dtype): @@ -58,10 +54,7 @@ def test_unique_null(null_obj, index_or_series_obj): unique_values_not_null = [val for val in unique_values_raw if not pd.isnull(val)] unique_values = [null_obj] + unique_values_not_null - if isinstance(obj, pd.Index) and obj._is_backward_compat_public_numeric_index: - expected = NumericIndex(unique_values, dtype=obj.dtype) - tm.assert_index_equal(result, expected, exact=True) - elif isinstance(obj, pd.Index): + if isinstance(obj, pd.Index): expected = pd.Index(unique_values, dtype=obj.dtype) if is_datetime64tz_dtype(obj.dtype): result = result.normalize() diff --git a/pandas/tests/indexes/common.py b/pandas/tests/indexes/common.py index 6b0046dbe619c..825c703b7972e 100644 --- a/pandas/tests/indexes/common.py +++ b/pandas/tests/indexes/common.py @@ -624,14 +624,10 @@ def test_map_dictlike(self, mapper, simple_index): # empty mappable dtype = None - if idx._is_backward_compat_public_numeric_index: - new_index_cls = NumericIndex - if idx.dtype.kind == "f": - dtype = idx.dtype - else: - new_index_cls = Float64Index + if idx.dtype.kind == "f": + dtype = idx.dtype - expected = new_index_cls([np.nan] * len(idx), dtype=dtype) + expected = Index([np.nan] * len(idx), dtype=dtype) result = idx.map(mapper(expected, idx)) tm.assert_index_equal(result, expected) @@ -880,13 +876,9 @@ def test_insert_na(self, nulls_fixture, simple_index): expected = Index([index[0], pd.NaT] + list(index[1:]), dtype=object) else: expected = Index([index[0], np.nan] + list(index[1:])) - - if index._is_backward_compat_public_numeric_index: - # GH#43921 we preserve NumericIndex - if index.dtype.kind == "f": - expected = NumericIndex(expected, dtype=index.dtype) - else: - expected = NumericIndex(expected) + # GH#43921 we preserve float dtype + if index.dtype.kind == "f": + expected = Index(expected, dtype=index.dtype) result = index.insert(1, na_val) tm.assert_index_equal(result, expected, exact=True) diff --git a/pandas/tests/indexes/test_base.py b/pandas/tests/indexes/test_base.py index af15cbc2f7929..1012734bab234 100644 --- a/pandas/tests/indexes/test_base.py +++ b/pandas/tests/indexes/test_base.py @@ -18,6 +18,8 @@ ) from pandas.util._test_decorators import async_mark +from pandas.core.dtypes.common import is_numeric_dtype + import pandas as pd from pandas import ( CategoricalIndex, @@ -592,13 +594,11 @@ def test_map_dictlike(self, index, mapper, request): if index.empty: # to match proper result coercion for uints expected = Index([]) - elif index._is_backward_compat_public_numeric_index: + elif is_numeric_dtype(index.dtype): expected = index._constructor(rng, dtype=index.dtype) elif type(index) is Index and index.dtype != object: # i.e. EA-backed, for now just Nullable expected = Index(rng, dtype=index.dtype) - elif index.dtype.kind == "u": - expected = Index(rng, dtype=index.dtype) else: expected = Index(rng)