From 58a4f33510df3efd5d488334a324d19144f27b2c Mon Sep 17 00:00:00 2001 From: Brock Date: Wed, 13 Oct 2021 15:11:36 -0700 Subject: [PATCH 1/2] BUG: RangeIndex.union --- doc/source/whatsnew/v1.4.0.rst | 1 + pandas/core/indexes/range.py | 7 +++++-- pandas/tests/indexes/ranges/test_setops.py | 8 ++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v1.4.0.rst b/doc/source/whatsnew/v1.4.0.rst index c5a22d8766a96..835256d7f7d42 100644 --- a/doc/source/whatsnew/v1.4.0.rst +++ b/doc/source/whatsnew/v1.4.0.rst @@ -548,6 +548,7 @@ Styler Other ^^^^^ - Bug in :meth:`CustomBusinessMonthBegin.__add__` (:meth:`CustomBusinessMonthEnd.__add__`) not applying the extra ``offset`` parameter when beginning (end) of the target month is already a business day (:issue:`41356`) +- Bug in :meth:`RangeIndex.union` with another ``RangeIndex`` with matching (even) ``step`` and starts differing by strictly less than ``step / 2`` (:issue:`??`) .. ***DO NOT USE THIS SECTION*** diff --git a/pandas/core/indexes/range.py b/pandas/core/indexes/range.py index 90649ad2dcbc1..0ac9b43309ed2 100644 --- a/pandas/core/indexes/range.py +++ b/pandas/core/indexes/range.py @@ -635,10 +635,13 @@ def _union(self, other: Index, sort): return type(self)(start_r, end_r + step_s, step_s) if ( (step_s % 2 == 0) - and (abs(start_s - start_o) <= step_s / 2) - and (abs(end_s - end_o) <= step_s / 2) + and (abs(start_s - start_o) == step_s / 2) + and (abs(end_s - end_o) == step_s / 2) ): + # e.g. range(0, 10, 2) and range(1, 11, 2) + # but not range(0, 20, 4) and range(1, 21, 4) GH#?? return type(self)(start_r, end_r + step_s / 2, step_s / 2) + elif step_o % step_s == 0: if ( (start_o - start_s) % step_s == 0 diff --git a/pandas/tests/indexes/ranges/test_setops.py b/pandas/tests/indexes/ranges/test_setops.py index e81271d8ee306..a7b611128747c 100644 --- a/pandas/tests/indexes/ranges/test_setops.py +++ b/pandas/tests/indexes/ranges/test_setops.py @@ -290,6 +290,14 @@ def test_union_sorted(self, unions): tm.assert_index_equal(res2, expected_sorted, exact=True) tm.assert_index_equal(res3, expected_sorted, exact="equiv") + def test_union_same_step_misaligned(self): + left = RangeIndex(range(0, 20, 4)) + right = RangeIndex(range(1, 21, 4)) + + result = left.union(right) + expected = Int64Index([0, 1, 4, 5, 8, 9, 12, 13, 16, 17]) + tm.assert_index_equal(result, expected, exact=True) + def test_difference(self): # GH#12034 Cases where we operate against another RangeIndex and may # get back another RangeIndex From 78d7e2be715ab934ea1fef9bbda90b712c35e71c Mon Sep 17 00:00:00 2001 From: Brock Date: Wed, 13 Oct 2021 15:12:20 -0700 Subject: [PATCH 2/2] GH ref --- doc/source/whatsnew/v1.4.0.rst | 2 +- pandas/core/indexes/range.py | 2 +- pandas/tests/indexes/ranges/test_setops.py | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v1.4.0.rst b/doc/source/whatsnew/v1.4.0.rst index 835256d7f7d42..d17329902f343 100644 --- a/doc/source/whatsnew/v1.4.0.rst +++ b/doc/source/whatsnew/v1.4.0.rst @@ -548,7 +548,7 @@ Styler Other ^^^^^ - Bug in :meth:`CustomBusinessMonthBegin.__add__` (:meth:`CustomBusinessMonthEnd.__add__`) not applying the extra ``offset`` parameter when beginning (end) of the target month is already a business day (:issue:`41356`) -- Bug in :meth:`RangeIndex.union` with another ``RangeIndex`` with matching (even) ``step`` and starts differing by strictly less than ``step / 2`` (:issue:`??`) +- Bug in :meth:`RangeIndex.union` with another ``RangeIndex`` with matching (even) ``step`` and starts differing by strictly less than ``step / 2`` (:issue:`44019`) .. ***DO NOT USE THIS SECTION*** diff --git a/pandas/core/indexes/range.py b/pandas/core/indexes/range.py index 0ac9b43309ed2..55628ae014ea0 100644 --- a/pandas/core/indexes/range.py +++ b/pandas/core/indexes/range.py @@ -639,7 +639,7 @@ def _union(self, other: Index, sort): and (abs(end_s - end_o) == step_s / 2) ): # e.g. range(0, 10, 2) and range(1, 11, 2) - # but not range(0, 20, 4) and range(1, 21, 4) GH#?? + # but not range(0, 20, 4) and range(1, 21, 4) GH#44019 return type(self)(start_r, end_r + step_s / 2, step_s / 2) elif step_o % step_s == 0: diff --git a/pandas/tests/indexes/ranges/test_setops.py b/pandas/tests/indexes/ranges/test_setops.py index a7b611128747c..07ec70c109f67 100644 --- a/pandas/tests/indexes/ranges/test_setops.py +++ b/pandas/tests/indexes/ranges/test_setops.py @@ -291,6 +291,7 @@ def test_union_sorted(self, unions): tm.assert_index_equal(res3, expected_sorted, exact="equiv") def test_union_same_step_misaligned(self): + # GH#44019 left = RangeIndex(range(0, 20, 4)) right = RangeIndex(range(1, 21, 4))