Skip to content

Commit c289b10

Browse files
jbrockmendeljreback
authored andcommitted
Fix PeriodIndex.get_indexer with non-PI (#30686)
1 parent 7f9e573 commit c289b10

File tree

2 files changed

+38
-15
lines changed

2 files changed

+38
-15
lines changed

pandas/core/indexes/period.py

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -565,15 +565,12 @@ def get_value(self, series, key):
565565
def get_indexer(self, target, method=None, limit=None, tolerance=None):
566566
target = ensure_index(target)
567567

568-
if hasattr(target, "freq") and target.freq != self.freq:
569-
msg = DIFFERENT_FREQ.format(
570-
cls=type(self).__name__,
571-
own_freq=self.freqstr,
572-
other_freq=target.freqstr,
573-
)
574-
raise IncompatibleFrequency(msg)
575-
576568
if isinstance(target, PeriodIndex):
569+
if target.freq != self.freq:
570+
# No matches
571+
no_matches = -1 * np.ones(self.shape, dtype=np.intp)
572+
return no_matches
573+
577574
target = target.asi8
578575
self_index = self._int64index
579576
else:
@@ -588,14 +585,11 @@ def get_indexer_non_unique(self, target):
588585
target = ensure_index(target)
589586

590587
if isinstance(target, PeriodIndex):
588+
if target.freq != self.freq:
589+
no_matches = -1 * np.ones(self.shape, dtype=np.intp)
590+
return no_matches, no_matches
591+
591592
target = target.asi8
592-
if hasattr(target, "freq") and target.freq != self.freq:
593-
msg = DIFFERENT_FREQ.format(
594-
cls=type(self).__name__,
595-
own_freq=self.freqstr,
596-
other_freq=target.freqstr,
597-
)
598-
raise IncompatibleFrequency(msg)
599593

600594
indexer, missing = self._int64index.get_indexer_non_unique(target)
601595
return ensure_platform_int(indexer), missing

pandas/tests/indexes/period/test_indexing.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,35 @@ def test_get_indexer(self):
550550
res = idx.get_indexer(target, "nearest", tolerance=pd.Timedelta("1 day"))
551551
tm.assert_numpy_array_equal(res, np.array([0, 0, 1, -1], dtype=np.intp))
552552

553+
def test_get_indexer_mismatched_dtype(self):
554+
# Check that we return all -1s and do not raise or cast incorrectly
555+
556+
dti = pd.date_range("2016-01-01", periods=3)
557+
pi = dti.to_period("D")
558+
pi2 = dti.to_period("W")
559+
560+
expected = np.array([-1, -1, -1], dtype=np.intp)
561+
562+
result = pi.get_indexer(dti)
563+
tm.assert_numpy_array_equal(result, expected)
564+
565+
# This should work in both directions
566+
result = dti.get_indexer(pi)
567+
tm.assert_numpy_array_equal(result, expected)
568+
569+
result = pi.get_indexer(pi2)
570+
tm.assert_numpy_array_equal(result, expected)
571+
572+
# We expect the same from get_indexer_non_unique
573+
result = pi.get_indexer_non_unique(dti)[0]
574+
tm.assert_numpy_array_equal(result, expected)
575+
576+
result = dti.get_indexer_non_unique(pi)[0]
577+
tm.assert_numpy_array_equal(result, expected)
578+
579+
result = pi.get_indexer_non_unique(pi2)[0]
580+
tm.assert_numpy_array_equal(result, expected)
581+
553582
def test_get_indexer_non_unique(self):
554583
# GH 17717
555584
p1 = pd.Period("2017-09-02")

0 commit comments

Comments
 (0)