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.