Skip to content

REF: require scalar in IntervalIndex.get_loc, get_value #31169

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 8 commits into from
Jan 24, 2020
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