Skip to content

Commit 9a211aa

Browse files
jbrockmendeljreback
authored andcommitted
BUG: inconsistency between PeriodIndex.get_value vs get_loc (#31172)
1 parent 2038d7a commit 9a211aa

File tree

3 files changed

+30
-6
lines changed

3 files changed

+30
-6
lines changed

doc/source/whatsnew/v1.1.0.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ Interval
144144
Indexing
145145
^^^^^^^^
146146
- 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`)
147-
-
147+
- Bug in :meth:`PeriodIndex.get_loc` treating higher-resolution strings differently from :meth:`PeriodIndex.get_value` (:issue:`31172`)
148148
-
149149

150150
Missing

pandas/core/indexes/period.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ def get_value(self, series, key):
486486
try:
487487
loc = self._get_string_slice(key)
488488
return series[loc]
489-
except (TypeError, ValueError):
489+
except (TypeError, ValueError, OverflowError):
490490
pass
491491

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

569569
if isinstance(key, str):
570+
570571
try:
571-
return self._get_string_slice(key)
572-
except (TypeError, KeyError, ValueError, OverflowError):
572+
loc = self._get_string_slice(key)
573+
return loc
574+
except (TypeError, ValueError):
573575
pass
574576

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

583+
grp = resolution.Resolution.get_freq_group(reso)
584+
freqn = resolution.get_freq_group(self.freq)
585+
586+
# _get_string_slice will handle cases where grp < freqn
587+
assert grp >= freqn
588+
589+
if grp == freqn:
590+
key = Period(asdt, freq=self.freq)
591+
loc = self.get_loc(key, method=method, tolerance=tolerance)
592+
return loc
593+
elif method is None:
594+
raise KeyError(key)
595+
else:
596+
key = asdt
597+
582598
elif is_integer(key):
583599
# Period constructor will cast to string, which we dont want
584600
raise KeyError(key)

pandas/tests/indexes/period/test_indexing.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -518,12 +518,20 @@ def test_contains(self):
518518

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

522523
for p in ps0:
523524
assert p in idx0
524525
assert str(p) in idx0
525526

526-
assert "2017-09-01 00:00:01" in idx0
527+
# GH#31172
528+
# Higher-resolution period-like are _not_ considered as contained
529+
key = "2017-09-01 00:00:01"
530+
assert key not in idx0
531+
with pytest.raises(KeyError, match=key):
532+
idx0.get_loc(key)
533+
with pytest.raises(KeyError, match=key):
534+
idx0.get_value(ser, key)
527535

528536
assert "2017-09" in idx0
529537

0 commit comments

Comments
 (0)