From 1c545b92445a5e9af0e854603249afabf6c6db7d Mon Sep 17 00:00:00 2001 From: arthurlw Date: Sun, 14 Sep 2025 14:26:53 -0700 Subject: [PATCH 1/4] Updated condition and added test --- pandas/core/indexes/datetimelike.py | 2 +- pandas/tests/indexes/datetimes/test_setops.py | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py index 7e6461f0fab5e..183267efd8170 100644 --- a/pandas/core/indexes/datetimelike.py +++ b/pandas/core/indexes/datetimelike.py @@ -627,7 +627,7 @@ def _fast_intersect(self, other, sort): def _can_fast_intersect(self, other: Self) -> bool: # Note: we only get here with len(self) > 0 and len(other) > 0 - if self.freq is None: + if self.freq is None or self.freq == "C": return False elif other.freq != self.freq: diff --git a/pandas/tests/indexes/datetimes/test_setops.py b/pandas/tests/indexes/datetimes/test_setops.py index 7a68cb867c94e..20920c131232a 100644 --- a/pandas/tests/indexes/datetimes/test_setops.py +++ b/pandas/tests/indexes/datetimes/test_setops.py @@ -7,6 +7,7 @@ import numpy as np import pytest +from pandas._libs.tslibs.timedeltas import Timedelta import pandas.util._test_decorators as td import pandas as pd @@ -709,7 +710,6 @@ def test_intersection_bug(self): b = bdate_range("12/10/2011", "12/20/2011", freq="C") result = a.intersection(b) tm.assert_index_equal(result, b) - assert result.freq == b.freq @pytest.mark.parametrize( "tz", [None, "UTC", "Europe/Berlin", timezone(timedelta(hours=-1))] @@ -757,3 +757,16 @@ def test_intersection_non_nano_rangelike(): freq="D", ) tm.assert_index_equal(result, expected) + + +def test_cday_intersection_empty(): + # GH#44025 + off = pd.offsets.CDay(1, normalize=False) + ts = Timestamp("2021-10-13 09:00") + ts2 = ts + Timedelta("1 hour") + + dti1 = date_range(start=ts, periods=10, freq=off) + dti2 = date_range(start=ts2, periods=10, freq=off) + result = dti1.intersection(dti2) + expected = DatetimeIndex([], dtype="datetime64[ns]") + tm.assert_index_equal(result, expected) From 8265c7d40c870b34c639bcf76582ede766fdde46 Mon Sep 17 00:00:00 2001 From: arthurlw Date: Fri, 17 Oct 2025 17:42:16 -0700 Subject: [PATCH 2/4] Updated condition logic --- pandas/core/indexes/datetimelike.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py index 183267efd8170..25931628079b8 100644 --- a/pandas/core/indexes/datetimelike.py +++ b/pandas/core/indexes/datetimelike.py @@ -626,8 +626,7 @@ def _fast_intersect(self, other, sort): return result def _can_fast_intersect(self, other: Self) -> bool: - # Note: we only get here with len(self) > 0 and len(other) > 0 - if self.freq is None or self.freq == "C": + if self.freq is None: return False elif other.freq != self.freq: @@ -637,6 +636,13 @@ def _can_fast_intersect(self, other: Self) -> bool: # Because freq is not None, we must then be monotonic decreasing return False + # for non-anchored frequencies, need to check that the two + # indexes actually share a common point + # GH#44025 + diff = other[0] - self[0] + if diff != Timedelta(0) and diff.total_seconds() % 86400 != 0: + return False + # this along with matching freqs ensure that we "line up", # so intersection will preserve freq # Note we are assuming away Ticks, as those go through _range_intersect From 526bcc6b45af766d6e6f046719695b00ed7ffea7 Mon Sep 17 00:00:00 2001 From: arthurlw Date: Fri, 17 Oct 2025 17:44:47 -0700 Subject: [PATCH 3/4] add comment back --- pandas/core/indexes/datetimelike.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py index 25931628079b8..08588b8795668 100644 --- a/pandas/core/indexes/datetimelike.py +++ b/pandas/core/indexes/datetimelike.py @@ -626,6 +626,7 @@ def _fast_intersect(self, other, sort): return result def _can_fast_intersect(self, other: Self) -> bool: + # Note: we only get here with len(self) > 0 and len(other) > 0 if self.freq is None: return False From 7cee4497b3a004c57c20a915d551bd4d799faca9 Mon Sep 17 00:00:00 2001 From: arthurlw Date: Fri, 17 Oct 2025 17:49:52 -0700 Subject: [PATCH 4/4] add removed test condition --- pandas/tests/indexes/datetimes/test_setops.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/tests/indexes/datetimes/test_setops.py b/pandas/tests/indexes/datetimes/test_setops.py index 20920c131232a..230fd67bc9b82 100644 --- a/pandas/tests/indexes/datetimes/test_setops.py +++ b/pandas/tests/indexes/datetimes/test_setops.py @@ -710,6 +710,7 @@ def test_intersection_bug(self): b = bdate_range("12/10/2011", "12/20/2011", freq="C") result = a.intersection(b) tm.assert_index_equal(result, b) + assert result.freq == b.freq @pytest.mark.parametrize( "tz", [None, "UTC", "Europe/Berlin", timezone(timedelta(hours=-1))]