Skip to content

Commit

Permalink
BUG: inconsistency between PeriodIndex.get_value vs get_loc (#31172)
Browse files Browse the repository at this point in the history
  • Loading branch information
jbrockmendel authored and jreback committed Jan 25, 2020
1 parent 2038d7a commit 9a211aa
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 6 deletions.
2 changes: 1 addition & 1 deletion doc/source/whatsnew/v1.1.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ Interval
Indexing
^^^^^^^^
- Bug in slicing on a :class:`DatetimeIndex` with a partial-timestamp dropping high-resolution indices near the end of a year, quarter, or month (:issue:`31064`)
-
- Bug in :meth:`PeriodIndex.get_loc` treating higher-resolution strings differently from :meth:`PeriodIndex.get_value` (:issue:`31172`)
-

Missing
Expand Down
24 changes: 20 additions & 4 deletions pandas/core/indexes/period.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ def get_value(self, series, key):
try:
loc = self._get_string_slice(key)
return series[loc]
except (TypeError, ValueError):
except (TypeError, ValueError, OverflowError):
pass

asdt, reso = parse_time_string(key, self.freq)
Expand Down Expand Up @@ -567,18 +567,34 @@ def get_loc(self, key, method=None, tolerance=None):
"""

if isinstance(key, str):

try:
return self._get_string_slice(key)
except (TypeError, KeyError, ValueError, OverflowError):
loc = self._get_string_slice(key)
return loc
except (TypeError, ValueError):
pass

try:
asdt, reso = parse_time_string(key, self.freq)
key = asdt
except DateParseError:
# A string with invalid format
raise KeyError(f"Cannot interpret '{key}' as period")

grp = resolution.Resolution.get_freq_group(reso)
freqn = resolution.get_freq_group(self.freq)

# _get_string_slice will handle cases where grp < freqn
assert grp >= freqn

if grp == freqn:
key = Period(asdt, freq=self.freq)
loc = self.get_loc(key, method=method, tolerance=tolerance)
return loc
elif method is None:
raise KeyError(key)
else:
key = asdt

elif is_integer(key):
# Period constructor will cast to string, which we dont want
raise KeyError(key)
Expand Down
10 changes: 9 additions & 1 deletion pandas/tests/indexes/period/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -518,12 +518,20 @@ def test_contains(self):

ps0 = [p0, p1, p2]
idx0 = pd.PeriodIndex(ps0)
ser = pd.Series(range(6, 9), index=idx0)

for p in ps0:
assert p in idx0
assert str(p) in idx0

assert "2017-09-01 00:00:01" in idx0
# GH#31172
# Higher-resolution period-like are _not_ considered as contained
key = "2017-09-01 00:00:01"
assert key not in idx0
with pytest.raises(KeyError, match=key):
idx0.get_loc(key)
with pytest.raises(KeyError, match=key):
idx0.get_value(ser, key)

assert "2017-09" in idx0

Expand Down

0 comments on commit 9a211aa

Please sign in to comment.