Skip to content

Commit 936a990

Browse files
jbrockmendeljreback
authored andcommitted
Implement ExtensionIndex (#30703)
1 parent 863a6a4 commit 936a990

File tree

4 files changed

+39
-26
lines changed

4 files changed

+39
-26
lines changed

pandas/core/indexes/category.py

+3-16
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
from pandas._libs.hashtable import duplicated_int64
1111
from pandas._typing import AnyArrayLike
1212
import pandas.compat as compat
13-
from pandas.compat.numpy import function as nv
1413
from pandas.util._decorators import Appender, cache_readonly
1514

1615
from pandas.core.dtypes.common import (
@@ -30,7 +29,7 @@
3029
import pandas.core.common as com
3130
import pandas.core.indexes.base as ibase
3231
from pandas.core.indexes.base import Index, _index_shared_docs, maybe_extract_name
33-
from pandas.core.indexes.extension import make_wrapped_comparison_op
32+
from pandas.core.indexes.extension import ExtensionIndex, make_wrapped_comparison_op
3433
import pandas.core.missing as missing
3534
from pandas.core.ops import get_op_result_name
3635

@@ -67,7 +66,7 @@
6766
typ="method",
6867
overwrite=True,
6968
)
70-
class CategoricalIndex(Index, accessor.PandasDelegate):
69+
class CategoricalIndex(ExtensionIndex, accessor.PandasDelegate):
7170
"""
7271
Index based on an underlying :class:`Categorical`.
7372
@@ -723,20 +722,8 @@ def _convert_arr_indexer(self, keyarr):
723722
def _convert_index_indexer(self, keyarr):
724723
return self._shallow_copy(keyarr)
725724

726-
@Appender(_index_shared_docs["take"] % _index_doc_kwargs)
727-
def take(self, indices, axis=0, allow_fill=True, fill_value=None, **kwargs):
728-
nv.validate_take(tuple(), kwargs)
729-
indices = ensure_platform_int(indices)
730-
taken = self._assert_take_fillable(
731-
self._data,
732-
indices,
733-
allow_fill=allow_fill,
734-
fill_value=fill_value,
735-
na_value=self._data.dtype.na_value,
736-
)
737-
return self._shallow_copy(taken)
738-
739725
def take_nd(self, *args, **kwargs):
726+
"""Alias for `take`"""
740727
warnings.warn(
741728
"CategoricalIndex.take_nd is deprecated, use CategoricalIndex.take instead",
742729
FutureWarning,

pandas/core/indexes/datetimelike.py

+10-8
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,12 @@
4141

4242
from pandas.tseries.frequencies import DateOffset, to_offset
4343

44-
from .extension import inherit_names, make_wrapped_arith_op, make_wrapped_comparison_op
44+
from .extension import (
45+
ExtensionIndex,
46+
inherit_names,
47+
make_wrapped_arith_op,
48+
make_wrapped_comparison_op,
49+
)
4550

4651
_index_doc_kwargs = dict(ibase._index_doc_kwargs)
4752

@@ -81,7 +86,7 @@ def wrapper(left, right):
8186
["__iter__", "mean", "freq", "freqstr", "_ndarray_values", "asi8", "_box_values"],
8287
DatetimeLikeArrayMixin,
8388
)
84-
class DatetimeIndexOpsMixin(ExtensionOpsMixin):
89+
class DatetimeIndexOpsMixin(ExtensionIndex, ExtensionOpsMixin):
8590
"""
8691
Common ops mixin to support a unified interface datetimelike Index.
8792
"""
@@ -246,16 +251,13 @@ def take(self, indices, axis=0, allow_fill=True, fill_value=None, **kwargs):
246251
if isinstance(maybe_slice, slice):
247252
return self[maybe_slice]
248253

249-
taken = self._assert_take_fillable(
250-
self._data,
251-
indices,
252-
allow_fill=allow_fill,
253-
fill_value=fill_value,
254-
na_value=NaT,
254+
taken = ExtensionIndex.take(
255+
self, indices, axis, allow_fill, fill_value, **kwargs
255256
)
256257

257258
# keep freq in PeriodArray/Index, reset otherwise
258259
freq = self.freq if is_period_dtype(self) else None
260+
assert taken.freq == freq, (taken.freq, freq, taken)
259261
return self._shallow_copy(taken, freq=freq)
260262

261263
_can_hold_na = True

pandas/core/indexes/extension.py

+24
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@
33
"""
44
from typing import List
55

6+
from pandas.compat.numpy import function as nv
67
from pandas.util._decorators import cache_readonly
78

9+
from pandas.core.dtypes.common import ensure_platform_int
810
from pandas.core.dtypes.generic import ABCSeries
911

12+
from pandas.core.arrays import ExtensionArray
1013
from pandas.core.ops import get_op_result_name
1114

1215
from .base import Index
@@ -152,3 +155,24 @@ def _maybe_unwrap_index(obj):
152155
if isinstance(obj, Index):
153156
return obj._data
154157
return obj
158+
159+
160+
class ExtensionIndex(Index):
161+
"""
162+
Index subclass for indexes backed by ExtensionArray.
163+
"""
164+
165+
_data: ExtensionArray
166+
167+
def take(self, indices, axis=0, allow_fill=True, fill_value=None, **kwargs):
168+
nv.validate_take(tuple(), kwargs)
169+
indices = ensure_platform_int(indices)
170+
171+
taken = self._assert_take_fillable(
172+
self._data,
173+
indices,
174+
allow_fill=allow_fill,
175+
fill_value=fill_value,
176+
na_value=self._na_value,
177+
)
178+
return type(self)(taken, name=self.name)

pandas/core/indexes/interval.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
from pandas.tseries.frequencies import to_offset
5959
from pandas.tseries.offsets import DateOffset
6060

61-
from .extension import inherit_names
61+
from .extension import ExtensionIndex, inherit_names
6262

6363
_VALID_CLOSED = {"left", "right", "both", "neither"}
6464
_index_doc_kwargs = dict(ibase._index_doc_kwargs)
@@ -213,7 +213,7 @@ def func(intvidx_self, other, sort=False):
213213
overwrite=True,
214214
)
215215
@inherit_names(["is_non_overlapping_monotonic", "mid"], IntervalArray, cache=True)
216-
class IntervalIndex(IntervalMixin, Index, accessor.PandasDelegate):
216+
class IntervalIndex(IntervalMixin, ExtensionIndex, accessor.PandasDelegate):
217217
_typ = "intervalindex"
218218
_comparables = ["name"]
219219
_attributes = ["name", "closed"]

0 commit comments

Comments
 (0)