Skip to content

Commit 62dc098

Browse files
Backport PR #42115: REGR: DatetimeIndex.intersection #42104 (#42154)
Co-authored-by: jbrockmendel <[email protected]>
1 parent 0bfbbdf commit 62dc098

File tree

3 files changed

+22
-2
lines changed

3 files changed

+22
-2
lines changed

doc/source/whatsnew/v1.3.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -915,6 +915,7 @@ Datetimelike
915915
- Bug in constructing a :class:`DataFrame` or :class:`Series` with mismatched ``datetime64`` data and ``timedelta64`` dtype, or vice-versa, failing to raise a ``TypeError`` (:issue:`38575`, :issue:`38764`, :issue:`38792`)
916916
- Bug in constructing a :class:`Series` or :class:`DataFrame` with a ``datetime`` object out of bounds for ``datetime64[ns]`` dtype or a ``timedelta`` object out of bounds for ``timedelta64[ns]`` dtype (:issue:`38792`, :issue:`38965`)
917917
- Bug in :meth:`DatetimeIndex.intersection`, :meth:`DatetimeIndex.symmetric_difference`, :meth:`PeriodIndex.intersection`, :meth:`PeriodIndex.symmetric_difference` always returning object-dtype when operating with :class:`CategoricalIndex` (:issue:`38741`)
918+
- Bug in :meth:`DatetimeIndex.intersection` giving incorrect results with non-Tick frequencies with ``n != 1`` (:issue:`42104`)
918919
- Bug in :meth:`Series.where` incorrectly casting ``datetime64`` values to ``int64`` (:issue:`37682`)
919920
- Bug in :class:`Categorical` incorrectly typecasting ``datetime`` object to ``Timestamp`` (:issue:`38878`)
920921
- Bug in comparisons between :class:`Timestamp` object and ``datetime64`` objects just outside the implementation bounds for nanosecond ``datetime64`` (:issue:`39221`)

pandas/core/indexes/datetimelike.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -687,7 +687,8 @@ def _can_fast_intersect(self: _T, other: _T) -> bool:
687687
elif self.freq.is_anchored():
688688
# this along with matching freqs ensure that we "line up",
689689
# so intersection will preserve freq
690-
return True
690+
# GH#42104
691+
return self.freq.n == 1
691692

692693
elif isinstance(self.freq, Tick):
693694
# We "line up" if and only if the difference between two of our points
@@ -696,7 +697,8 @@ def _can_fast_intersect(self: _T, other: _T) -> bool:
696697
remainder = diff % self.freq.delta
697698
return remainder == Timedelta(0)
698699

699-
return True
700+
# GH#42104
701+
return self.freq.n == 1
700702

701703
def _can_fast_union(self: _T, other: _T) -> bool:
702704
# Assumes that type(self) == type(other), as per the annotation

pandas/tests/indexes/datetimes/test_setops.py

+17
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,23 @@ def test_setops_preserve_freq(self, tz):
391391
assert result.freq == rng.freq
392392
assert result.tz == rng.tz
393393

394+
def test_intersection_non_tick_no_fastpath(self):
395+
# GH#42104
396+
dti = DatetimeIndex(
397+
[
398+
"2018-12-31",
399+
"2019-03-31",
400+
"2019-06-30",
401+
"2019-09-30",
402+
"2019-12-31",
403+
"2020-03-31",
404+
],
405+
freq="Q-DEC",
406+
)
407+
result = dti[::2].intersection(dti[1::2])
408+
expected = dti[:0]
409+
tm.assert_index_equal(result, expected)
410+
394411

395412
class TestBusinessDatetimeIndex:
396413
def setup_method(self, method):

0 commit comments

Comments
 (0)