Skip to content

BUG: PeriodIndex.get_loc should raise KeyError #34240

Closed
@TomAugspurger

Description

@TomAugspurger

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)
<ipython-input-12-3a472f211c46> in <module>
----> 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)
<ipython-input-14-436c3fe5a8ed> in <module>
----> 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)
<ipython-input-17-6445c229fb58> in <module>
----> 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugError ReportingIncorrect or improved errors from pandasIndexingRelated to indexing on series/frames, not to indexes themselvesPeriodPeriod data type

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions