From 53a877a22c24df4a51228c23395e68b98df147bd Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Sat, 4 Jan 2020 09:11:50 -0800 Subject: [PATCH] Fix PeriodIndex.get_indexer with non-PI --- pandas/core/indexes/period.py | 24 ++++++---------- pandas/tests/indexes/period/test_indexing.py | 29 ++++++++++++++++++++ 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/pandas/core/indexes/period.py b/pandas/core/indexes/period.py index 1cc37504b675f..363ff32519d27 100644 --- a/pandas/core/indexes/period.py +++ b/pandas/core/indexes/period.py @@ -564,15 +564,12 @@ def get_value(self, series, key): def get_indexer(self, target, method=None, limit=None, tolerance=None): target = ensure_index(target) - if hasattr(target, "freq") and target.freq != self.freq: - msg = DIFFERENT_FREQ.format( - cls=type(self).__name__, - own_freq=self.freqstr, - other_freq=target.freqstr, - ) - raise IncompatibleFrequency(msg) - if isinstance(target, PeriodIndex): + if target.freq != self.freq: + # No matches + no_matches = -1 * np.ones(self.shape, dtype=np.intp) + return no_matches + target = target.asi8 self_index = self._int64index else: @@ -587,14 +584,11 @@ def get_indexer_non_unique(self, target): target = ensure_index(target) if isinstance(target, PeriodIndex): + if target.freq != self.freq: + no_matches = -1 * np.ones(self.shape, dtype=np.intp) + return no_matches, no_matches + target = target.asi8 - if hasattr(target, "freq") and target.freq != self.freq: - msg = DIFFERENT_FREQ.format( - cls=type(self).__name__, - own_freq=self.freqstr, - other_freq=target.freqstr, - ) - raise IncompatibleFrequency(msg) indexer, missing = self._int64index.get_indexer_non_unique(target) return ensure_platform_int(indexer), missing diff --git a/pandas/tests/indexes/period/test_indexing.py b/pandas/tests/indexes/period/test_indexing.py index 8b5a2958c4c61..e95b4ae5397b4 100644 --- a/pandas/tests/indexes/period/test_indexing.py +++ b/pandas/tests/indexes/period/test_indexing.py @@ -550,6 +550,35 @@ def test_get_indexer(self): res = idx.get_indexer(target, "nearest", tolerance=pd.Timedelta("1 day")) tm.assert_numpy_array_equal(res, np.array([0, 0, 1, -1], dtype=np.intp)) + def test_get_indexer_mismatched_dtype(self): + # Check that we return all -1s and do not raise or cast incorrectly + + dti = pd.date_range("2016-01-01", periods=3) + pi = dti.to_period("D") + pi2 = dti.to_period("W") + + expected = np.array([-1, -1, -1], dtype=np.intp) + + result = pi.get_indexer(dti) + tm.assert_numpy_array_equal(result, expected) + + # This should work in both directions + result = dti.get_indexer(pi) + tm.assert_numpy_array_equal(result, expected) + + result = pi.get_indexer(pi2) + tm.assert_numpy_array_equal(result, expected) + + # We expect the same from get_indexer_non_unique + result = pi.get_indexer_non_unique(dti)[0] + tm.assert_numpy_array_equal(result, expected) + + result = dti.get_indexer_non_unique(pi)[0] + tm.assert_numpy_array_equal(result, expected) + + result = pi.get_indexer_non_unique(pi2)[0] + tm.assert_numpy_array_equal(result, expected) + def test_get_indexer_non_unique(self): # GH 17717 p1 = pd.Period("2017-09-02")