Skip to content

Commit 9d11e2a

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

File tree

3 files changed

+53
-30
lines changed

3 files changed

+53
-30
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

+33-10
Original file line numberDiff line numberDiff line change
@@ -393,11 +393,8 @@ def test_get_loc(self):
393393
with pytest.raises(KeyError, match=r"^1\.1$"):
394394
idx0.get_loc(1.1)
395395

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

403400
# get the location of p1/p2 from
@@ -418,11 +415,8 @@ def test_get_loc(self):
418415
with pytest.raises(KeyError, match=r"^1\.1$"):
419416
idx1.get_loc(1.1)
420417

421-
msg = (
422-
r"'PeriodIndex\(\['2017-09-02', '2017-09-02', '2017-09-03'\],"
423-
r" dtype='period\[D\]', freq='D'\)' is an invalid key"
424-
)
425-
with pytest.raises(TypeError, match=msg):
418+
msg = r"PeriodIndex\(\['2017-09-02', '2017-09-02', '2017-09-03'\]"
419+
with pytest.raises(KeyError, match=msg):
426420
idx1.get_loc(idx1)
427421

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

0 commit comments

Comments
 (0)