Skip to content

Commit da47af8

Browse files
committed
fix difference functionality for period indexes, add additional tests
1 parent 23e592f commit da47af8

File tree

3 files changed

+26
-1
lines changed

3 files changed

+26
-1
lines changed

pandas/core/indexes/base.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3406,7 +3406,7 @@ def difference(self, other, sort=None):
34063406
return self._wrap_difference_result(other, result)
34073407

34083408
def _difference(self, other, sort):
3409-
# overridden by RangeIndex
3409+
# overridden by RangeIndex, PeriodIndex
34103410
this = self
34113411
if isinstance(self, ABCCategoricalIndex) and self.hasnans and other.hasnans:
34123412
this = this.dropna()
@@ -6209,6 +6209,12 @@ def _maybe_downcast_for_indexing(self, other: Index) -> tuple[Index, Index]:
62096209
# let's instead try with a straight Index
62106210
self = Index(self._values)
62116211

6212+
elif self.inferred_type == 'string' and isinstance(other, ABCPeriodIndex):
6213+
try:
6214+
return self.astype(other.dtype), other
6215+
except:
6216+
return self, other
6217+
62126218
if not is_object_dtype(self.dtype) and is_object_dtype(other.dtype):
62136219
# Reverse op so we dont need to re-implement on the subclasses
62146220
other, self = other._maybe_downcast_for_indexing(self)

pandas/core/indexes/period.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,12 @@ def shift(self, periods: int = 1, freq=None) -> Self:
514514
)
515515
return self + periods
516516

517+
def _difference(self, other, sort=None):
518+
if not isinstance(other, PeriodIndex):
519+
self, other = self._maybe_downcast_for_indexing(other)
520+
521+
return super()._difference(other, sort=sort)
522+
517523

518524
def period_range(
519525
start=None,

pandas/tests/indexes/period/test_setops.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,19 @@ def test_difference(self, sort):
314314
expected = expected.sort_values()
315315
tm.assert_index_equal(result_difference, expected)
316316

317+
def test_difference_mismatched_dtypes(self, sort):
318+
# GH58971
319+
index = pd.period_range('2022-01-01', periods=5, freq='M')
320+
other = pd.Index(['2022-02', '2022-03'])
321+
322+
idx_diff = index.difference(other, sort)
323+
expected = pd.PeriodIndex(['2022-01', '2022-04', '2022-05'], freq='M')
324+
tm.assert_index_equal(idx_diff, expected)
325+
326+
idx_diff = other.difference(index, sort)
327+
expected = pd.Index([])
328+
tm.assert_index_equal(idx_diff, expected)
329+
317330
def test_difference_freq(self, sort):
318331
# GH14323: difference of Period MUST preserve frequency
319332
# but the ability to union results must be preserved

0 commit comments

Comments
 (0)