Skip to content

Implement ExtensionIndex #30703

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 3 additions & 16 deletions pandas/core/indexes/category.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from pandas._libs.hashtable import duplicated_int64
from pandas._typing import AnyArrayLike
import pandas.compat as compat
from pandas.compat.numpy import function as nv
from pandas.util._decorators import Appender, cache_readonly

from pandas.core.dtypes.common import (
Expand All @@ -30,7 +29,7 @@
import pandas.core.common as com
import pandas.core.indexes.base as ibase
from pandas.core.indexes.base import Index, _index_shared_docs, maybe_extract_name
from pandas.core.indexes.extension import make_wrapped_comparison_op
from pandas.core.indexes.extension import ExtensionIndex, make_wrapped_comparison_op
import pandas.core.missing as missing
from pandas.core.ops import get_op_result_name

Expand Down Expand Up @@ -67,7 +66,7 @@
typ="method",
overwrite=True,
)
class CategoricalIndex(Index, accessor.PandasDelegate):
class CategoricalIndex(ExtensionIndex, accessor.PandasDelegate):
"""
Index based on an underlying :class:`Categorical`.

Expand Down Expand Up @@ -723,20 +722,8 @@ def _convert_arr_indexer(self, keyarr):
def _convert_index_indexer(self, keyarr):
return self._shallow_copy(keyarr)

@Appender(_index_shared_docs["take"] % _index_doc_kwargs)
def take(self, indices, axis=0, allow_fill=True, fill_value=None, **kwargs):
nv.validate_take(tuple(), kwargs)
indices = ensure_platform_int(indices)
taken = self._assert_take_fillable(
self._data,
indices,
allow_fill=allow_fill,
fill_value=fill_value,
na_value=self._data.dtype.na_value,
)
return self._shallow_copy(taken)

def take_nd(self, *args, **kwargs):
"""Alias for `take`"""
warnings.warn(
"CategoricalIndex.take_nd is deprecated, use CategoricalIndex.take instead",
FutureWarning,
Expand Down
18 changes: 10 additions & 8 deletions pandas/core/indexes/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,12 @@

from pandas.tseries.frequencies import DateOffset, to_offset

from .extension import inherit_names, make_wrapped_arith_op, make_wrapped_comparison_op
from .extension import (
ExtensionIndex,
inherit_names,
make_wrapped_arith_op,
make_wrapped_comparison_op,
)

_index_doc_kwargs = dict(ibase._index_doc_kwargs)

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

taken = self._assert_take_fillable(
self._data,
indices,
allow_fill=allow_fill,
fill_value=fill_value,
na_value=NaT,
taken = ExtensionIndex.take(
self, indices, axis, allow_fill, fill_value, **kwargs
)

# keep freq in PeriodArray/Index, reset otherwise
freq = self.freq if is_period_dtype(self) else None
assert taken.freq == freq, (taken.freq, freq, taken)
return self._shallow_copy(taken, freq=freq)

_can_hold_na = True
Expand Down
24 changes: 24 additions & 0 deletions pandas/core/indexes/extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
"""
from typing import List

from pandas.compat.numpy import function as nv
from pandas.util._decorators import cache_readonly

from pandas.core.dtypes.common import ensure_platform_int
from pandas.core.dtypes.generic import ABCSeries

from pandas.core.arrays import ExtensionArray
from pandas.core.ops import get_op_result_name

from .base import Index
Expand Down Expand Up @@ -152,3 +155,24 @@ def _maybe_unwrap_index(obj):
if isinstance(obj, Index):
return obj._data
return obj


class ExtensionIndex(Index):
"""
Index subclass for indexes backed by ExtensionArray.
"""

_data: ExtensionArray

def take(self, indices, axis=0, allow_fill=True, fill_value=None, **kwargs):
nv.validate_take(tuple(), kwargs)
indices = ensure_platform_int(indices)

taken = self._assert_take_fillable(
self._data,
indices,
allow_fill=allow_fill,
fill_value=fill_value,
na_value=self._na_value,
)
return type(self)(taken, name=self.name)
4 changes: 2 additions & 2 deletions pandas/core/indexes/interval.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
from pandas.tseries.frequencies import to_offset
from pandas.tseries.offsets import DateOffset

from .extension import inherit_names
from .extension import ExtensionIndex, inherit_names

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