BUG: PeriodIndex.get_loc should raise KeyError (original) (raw)

Currently PeriodIndex.get_loc raises a ValueError rather than a KeyError.

In [11]: s = pd.Series([1, 2, 3], index=pd.period_range('2000', periods=3, name='A'))

In [12]: s.index.get_loc('A')

ValueError Traceback (most recent call last) in ----> 1 s.index.get_loc('A')

~/sandbox/pandas/pandas/core/indexes/period.py in get_loc(self, key, method, tolerance) 501 502 try: --> 503 asdt, reso = parse_time_string(key, self.freq) 504 except DateParseError as err: 505 # A string with invalid format

~/sandbox/pandas/pandas/_libs/tslibs/parsing.pyx in pandas._libs.tslibs.parsing.parse_time_string()

~/sandbox/pandas/pandas/_libs/tslibs/parsing.pyx in pandas._libs.tslibs.parsing.parse_datetime_string_with_reso()

ValueError: Given date string not likely a datetime.

Compare that with DatetimeIndex

In [13]: t = pd.Series([1, 2, 3], index=pd.date_range('2000', periods=3, name='A'))

In [14]: t.index.get_loc("A")

ValueError Traceback (most recent call last) ~/sandbox/pandas/pandas/_libs/tslibs/conversion.pyx in pandas._libs.tslibs.conversion.convert_str_to_tsobject()

~/sandbox/pandas/pandas/_libs/tslibs/parsing.pyx in pandas._libs.tslibs.parsing.parse_datetime_string()

ValueError: Given date string not likely a datetime.

During handling of the above exception, another exception occurred:

ValueError Traceback (most recent call last) ~/sandbox/pandas/pandas/core/indexes/datetimes.py in get_loc(self, key, method, tolerance) 566 try: --> 567 key = self._maybe_cast_for_get_loc(key) 568 except ValueError as err:

~/sandbox/pandas/pandas/core/indexes/datetimes.py in _maybe_cast_for_get_loc(self, key) 594 # needed to localize naive datetimes --> 595 key = Timestamp(key) 596 if key.tzinfo is None:

~/sandbox/pandas/pandas/_libs/tslibs/timestamps.pyx in pandas._libs.tslibs.timestamps.Timestamp.new()

~/sandbox/pandas/pandas/_libs/tslibs/conversion.pyx in pandas._libs.tslibs.conversion.convert_to_tsobject()

~/sandbox/pandas/pandas/_libs/tslibs/conversion.pyx in pandas._libs.tslibs.conversion.convert_str_to_tsobject()

ValueError: could not convert string to Timestamp

The above exception was the direct cause of the following exception:

KeyError Traceback (most recent call last) in ----> 1 t.index.get_loc("A")

~/sandbox/pandas/pandas/core/indexes/datetimes.py in get_loc(self, key, method, tolerance) 567 key = self._maybe_cast_for_get_loc(key) 568 except ValueError as err: --> 569 raise KeyError(key) from err 570 571 elif isinstance(key, timedelta):

KeyError: 'A'

This leads to other issues like Serie.__getitem__ and Series.__contains__:

In [16]: "A" in t Out[16]: False

In [17]: "A" in s

ValueError Traceback (most recent call last) in ----> 1 "A" in s

~/sandbox/pandas/pandas/core/generic.py in contains(self, key) 1739 def contains(self, key) -> bool_t: 1740 """True if the key is in the info axis""" -> 1741 return key in self._info_axis 1742 1743 @property

~/sandbox/pandas/pandas/util/_decorators.py in wrapper(*args, **kwargs) 353 @wraps(func) 354 def wrapper(*args, **kwargs) -> Callable: --> 355 return func(*args, **kwargs) 356 357 # collecting docstring and docstring templates

~/sandbox/pandas/pandas/core/indexes/period.py in contains(self, key) 332 hash(key) 333 try: --> 334 self.get_loc(key) 335 return True 336 except KeyError:

~/sandbox/pandas/pandas/core/indexes/period.py in get_loc(self, key, method, tolerance) 501 502 try: --> 503 asdt, reso = parse_time_string(key, self.freq) 504 except DateParseError as err: 505 # A string with invalid format

~/sandbox/pandas/pandas/_libs/tslibs/parsing.pyx in pandas._libs.tslibs.parsing.parse_time_string()

~/sandbox/pandas/pandas/_libs/tslibs/parsing.pyx in pandas._libs.tslibs.parsing.parse_datetime_string_with_reso()

ValueError: Given date string not likely a datetime.

As part of fixing this, we should revert the change to pandas/core/groupby/grouper.py in #34049.