Skip to content
42 changes: 18 additions & 24 deletions pandas/core/indexes/interval.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
""" define the IntervalIndex """
from operator import le, lt
import textwrap
from typing import Any, Optional, Tuple, Union
from typing import TYPE_CHECKING, Any, Optional, Tuple, Union

import numpy as np

Expand Down Expand Up @@ -34,7 +34,6 @@
is_object_dtype,
is_scalar,
)
from pandas.core.dtypes.generic import ABCSeries
from pandas.core.dtypes.missing import isna

from pandas.core import accessor
Expand All @@ -59,6 +58,10 @@
from pandas.tseries.frequencies import to_offset
from pandas.tseries.offsets import DateOffset

if TYPE_CHECKING:
from pandas import Series


_VALID_CLOSED = {"left", "right", "both", "neither"}
_index_doc_kwargs = dict(ibase._index_doc_kwargs)

Expand Down Expand Up @@ -681,7 +684,7 @@ def _searchsorted_monotonic(self, label, side, exclude_label=False):
return sub_idx._searchsorted_monotonic(label, side)

def get_loc(
self, key: Any, method: Optional[str] = None, tolerance=None
self, key, method: Optional[str] = None, tolerance=None
) -> Union[int, slice, np.ndarray]:
"""
Get integer location, slice or boolean mask for requested label.
Expand Down Expand Up @@ -723,10 +726,8 @@ def get_loc(
"""
self._check_method(method)

# list-like are invalid labels for II but in some cases may work, e.g
# single element array of comparable type, so guard against them early
if is_list_like(key):
raise KeyError(key)
if not is_scalar(key):
raise InvalidIndexError(key)

if isinstance(key, Interval):
if self.closed != key.closed:
Expand Down Expand Up @@ -819,6 +820,9 @@ def get_indexer(
loc = self.get_loc(key)
except KeyError:
loc = -1
except InvalidIndexError:
# i.e. non-scalar key
raise TypeError(key)
indexer.append(loc)

return ensure_platform_int(indexer)
Expand Down Expand Up @@ -882,25 +886,15 @@ def get_indexer_for(self, target: AnyArrayLike, **kwargs) -> np.ndarray:
return self.get_indexer(target, **kwargs)

@Appender(_index_shared_docs["get_value"] % _index_doc_kwargs)
def get_value(self, series: ABCSeries, key: Any) -> Any:

if com.is_bool_indexer(key):
loc = key
elif is_list_like(key):
if self.is_overlapping:
loc, missing = self.get_indexer_non_unique(key)
if len(missing):
raise KeyError
else:
loc = self.get_indexer(key)
elif isinstance(key, slice):
if not (key.step is None or key.step == 1):
raise ValueError("cannot support not-default step in a slice")
loc = self._convert_slice_indexer(key, kind="getitem")
else:
loc = self.get_loc(key)
def get_value(self, series: "Series", key):
loc = self.get_loc(key)
return series.iloc[loc]

def _convert_slice_indexer(self, key: slice, kind=None):
if not (key.step is None or key.step == 1):
raise ValueError("cannot support not-default step in a slice")
return super()._convert_slice_indexer(key, kind)

@Appender(_index_shared_docs["where"])
def where(self, cond, other=None):
if other is None:
Expand Down
4 changes: 4 additions & 0 deletions pandas/core/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
from pandas.core.indexes.api import (
Float64Index,
Index,
IntervalIndex,
InvalidIndexError,
MultiIndex,
ensure_index,
Expand Down Expand Up @@ -872,6 +873,9 @@ def _get_with(self, key):
if key_type == "integer":
if self.index.is_integer() or self.index.is_floating():
return self.loc[key]
elif isinstance(self.index, IntervalIndex):
indexer = self.index.get_indexer_for(key)
return self.iloc[indexer]
else:
return self._get_values(key)
elif key_type == "boolean":
Expand Down