Skip to content

Commit 6f690b0

Browse files
jbrockmendeljreback
authored andcommitted
BUG: TimedeltaIndex.union with sort=False (#30701)
1 parent f9e524c commit 6f690b0

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

pandas/core/indexes/timedeltas.py

+11-2
Original file line numberDiff line numberDiff line change
@@ -257,15 +257,15 @@ def _union(self, other: "TimedeltaIndex", sort):
257257
this, other = self, other
258258

259259
if this._can_fast_union(other):
260-
return this._fast_union(other)
260+
return this._fast_union(other, sort=sort)
261261
else:
262262
result = Index._union(this, other, sort=sort)
263263
if isinstance(result, TimedeltaIndex):
264264
if result.freq is None:
265265
result._set_freq("infer")
266266
return result
267267

268-
def _fast_union(self, other):
268+
def _fast_union(self, other, sort=None):
269269
if len(other) == 0:
270270
return self.view(type(self))
271271

@@ -275,6 +275,15 @@ def _fast_union(self, other):
275275
# to make our life easier, "sort" the two ranges
276276
if self[0] <= other[0]:
277277
left, right = self, other
278+
elif sort is False:
279+
# TDIs are not in the "correct" order and we don't want
280+
# to sort but want to remove overlaps
281+
left, right = self, other
282+
left_start = left[0]
283+
loc = right.searchsorted(left_start, side="left")
284+
right_chunk = right.values[:loc]
285+
dates = concat_compat((left.values, right_chunk))
286+
return self._shallow_copy(dates)
278287
else:
279288
left, right = other, self
280289

pandas/tests/indexes/timedeltas/test_setops.py

+16
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,22 @@ def test_union(self):
2222
i1.union(i2) # Works
2323
i2.union(i1) # Fails with "AttributeError: can't set attribute"
2424

25+
def test_union_sort_false(self):
26+
tdi = timedelta_range("1day", periods=5)
27+
28+
left = tdi[3:]
29+
right = tdi[:3]
30+
31+
# Check that we are testing the desired code path
32+
assert left._can_fast_union(right)
33+
34+
result = left.union(right)
35+
tm.assert_index_equal(result, tdi)
36+
37+
result = left.union(right, sort=False)
38+
expected = pd.TimedeltaIndex(["4 Days", "5 Days", "1 Days", "2 Day", "3 Days"])
39+
tm.assert_index_equal(result, expected)
40+
2541
def test_union_coverage(self):
2642

2743
idx = TimedeltaIndex(["3d", "1d", "2d"])

0 commit comments

Comments
 (0)