Skip to content

Commit 8cdf285

Browse files
committed
BUG: PeriodEngine doesn't work (#29038)
1 parent f03ed62 commit 8cdf285

File tree

3 files changed

+55
-26
lines changed

3 files changed

+55
-26
lines changed

pandas/core/indexes/period.py

+19-19
Original file line numberDiff line numberDiff line change
@@ -704,36 +704,36 @@ def get_loc(self, key, method=None, tolerance=None):
704704
-------
705705
loc : int
706706
"""
707+
if is_integer(key):
708+
ordinal = key
709+
else:
710+
key = self._cast_to_period_object(key)
711+
ordinal = iNaT if key is NaT else key.ordinal
712+
707713
try:
708-
return self._engine.get_loc(key)
714+
if tolerance is not None:
715+
tolerance = self._convert_tolerance(tolerance, np.asarray(key))
716+
return self._int64index.get_loc(ordinal, method, tolerance)
709717
except KeyError:
710-
if is_integer(key):
711-
raise
718+
raise KeyError(key)
712719

720+
def _cast_to_period_object(self, key):
721+
if isinstance(key, str):
713722
try:
714723
asdt, parsed, reso = parse_time_string(key, self.freq)
715724
key = asdt
716-
except TypeError:
717-
pass
718725
except DateParseError:
719726
# A string with invalid format
720727
raise KeyError("Cannot interpret '{}' as period".format(key))
721728

722-
try:
723-
key = Period(key, freq=self.freq)
724-
except ValueError:
725-
# we cannot construct the Period
726-
# as we have an invalid type
727-
raise KeyError(key)
728-
729-
try:
730-
ordinal = iNaT if key is NaT else key.ordinal
731-
if tolerance is not None:
732-
tolerance = self._convert_tolerance(tolerance, np.asarray(key))
733-
return self._int64index.get_loc(ordinal, method, tolerance)
729+
try:
730+
key = Period(key, freq=self.freq)
731+
except ValueError:
732+
# we cannot construct the Period
733+
# as we have an invalid type
734+
raise KeyError(key)
734735

735-
except KeyError:
736-
raise KeyError(key)
736+
return key
737737

738738
def _maybe_cast_slice_bound(self, label, side, kind):
739739
"""

pandas/tests/indexes/common.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ def test_memory_usage(self, indices):
331331

332332
# RangeIndex, IntervalIndex
333333
# don't have engines
334-
if not isinstance(indices, (RangeIndex, IntervalIndex)):
334+
if not isinstance(indices, (RangeIndex, IntervalIndex, PeriodIndex)):
335335
assert result2 > result
336336

337337
if indices.inferred_type == "object":

pandas/tests/indexes/period/test_indexing.py

+35-6
Original file line numberDiff line numberDiff line change
@@ -394,10 +394,10 @@ def test_get_loc(self):
394394
idx0.get_loc(1.1)
395395

396396
msg = (
397-
r"'PeriodIndex\(\['2017-09-01', '2017-09-02', '2017-09-03'\],"
398-
r" dtype='period\[D\]', freq='D'\)' is an invalid key"
397+
r"PeriodIndex\(\['2017-09-01', '2017-09-02', '2017-09-03'\], "
398+
r"dtype='period\[D\]', freq='D'\)"
399399
)
400-
with pytest.raises(TypeError, match=msg):
400+
with pytest.raises(KeyError, match=msg):
401401
idx0.get_loc(idx0)
402402

403403
# get the location of p1/p2 from
@@ -419,10 +419,10 @@ def test_get_loc(self):
419419
idx1.get_loc(1.1)
420420

421421
msg = (
422-
r"'PeriodIndex\(\['2017-09-02', '2017-09-02', '2017-09-03'\],"
423-
r" dtype='period\[D\]', freq='D'\)' is an invalid key"
422+
r"PeriodIndex\(\['2017-09-02', '2017-09-02', '2017-09-03'\], "
423+
r"dtype='period\[D\]', freq='D'\)"
424424
)
425-
with pytest.raises(TypeError, match=msg):
425+
with pytest.raises(KeyError, match=msg):
426426
idx1.get_loc(idx1)
427427

428428
# get the location of p1/p2 from
@@ -685,3 +685,32 @@ def test_period_index_indexer(self):
685685
tm.assert_frame_equal(df, df.loc[list(idx)])
686686
tm.assert_frame_equal(df.iloc[0:5], df.loc[idx[0:5]])
687687
tm.assert_frame_equal(df, df.loc[list(idx)])
688+
689+
def test_get_loc_not_use_engine(self):
690+
# issue 29234
691+
idx = PeriodIndex(
692+
["2014", "2015", "2016", "2017", np.datetime64("NaT")], freq="A"
693+
)
694+
695+
pi = PeriodIndex(["2016"], freq="A")
696+
msg = r"PeriodIndex\(\['2016'\], dtype='period\[A-DEC\]', freq='A-DEC'\)"
697+
with pytest.raises(KeyError, match=msg):
698+
idx.get_loc(pi)
699+
700+
ordinal = Period(2015, freq="A").ordinal
701+
assert idx.get_loc(ordinal) == 1
702+
703+
with pytest.raises(KeyError, match="2015"):
704+
idx.get_loc(2015)
705+
706+
with pytest.raises(KeyError, match="Cannot interpret 'foo-bar' as period"):
707+
idx.get_loc("foo-bar")
708+
709+
assert idx.get_loc("2015-01-01") == 1
710+
711+
with pytest.raises(KeyError, match=r"(2015, 2016)"):
712+
idx.get_loc((2015, 2016))
713+
714+
assert idx.get_loc(datetime(2016, 1, 1)) == 2
715+
716+
assert idx.get_loc(np.datetime64("NaT")) == 4

0 commit comments

Comments
 (0)