Skip to content

Commit ef1aa4d

Browse files
committed
BUG: Fix IntervalIndex.get_loc/get_indexer for IntervalIndex of length one
1 parent 28dbae9 commit ef1aa4d

File tree

3 files changed

+24
-1
lines changed

3 files changed

+24
-1
lines changed

doc/source/whatsnew/v0.23.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1245,6 +1245,7 @@ Indexing
12451245
- Bug in ``Series.is_unique`` where extraneous output in stderr is shown if Series contains objects with ``__ne__`` defined (:issue:`20661`)
12461246
- Bug in ``.loc`` assignment with a single-element list-like incorrectly assigns as a list (:issue:`19474`)
12471247
- Bug in partial string indexing on a ``Series/DataFrame`` with a monotonic decreasing ``DatetimeIndex`` (:issue:`19362`)
1248+
- Bug in ``IntervalIndex.get_loc()`` and ``IntervalIndex.get_indexer()`` when used with an :class:`IntervalIndex` containing a single interval (:issue:`17284`, :issue:`20921`)
12481249

12491250
MultiIndex
12501251
^^^^^^^^^^

pandas/core/indexes/interval.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -938,8 +938,11 @@ def _searchsorted_monotonic(self, label, side, exclude_label=False):
938938
if isinstance(label, IntervalMixin):
939939
raise NotImplementedError
940940

941+
# GH 20921: "not is_monotonic_increasing" for the second condition
942+
# instead of "is_monotonic_decreasing" to account for single element
943+
# indexes being both increasing and decreasing
941944
if ((side == 'left' and self.left.is_monotonic_increasing) or
942-
(side == 'right' and self.left.is_monotonic_decreasing)):
945+
(side == 'right' and not self.left.is_monotonic_increasing)):
943946
sub_idx = self.right
944947
if self.open_right or exclude_label:
945948
label = _get_next_label(label)

pandas/tests/indexes/interval/test_interval.py

+19
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,15 @@ def test_get_loc_interval(self):
497497
pytest.raises(KeyError, self.index.get_loc,
498498
Interval(-1, 0, 'left'))
499499

500+
# Make consistent with test_interval_new.py (see #16316, #16386)
501+
@pytest.mark.parametrize('item', [3, Interval(1, 4)])
502+
def test_get_loc_length_one(self, item, closed):
503+
# GH 20921
504+
index = IntervalIndex.from_tuples([(0, 5)], closed=closed)
505+
result = index.get_loc(item)
506+
expected = 0
507+
assert result == expected
508+
500509
# To be removed, replaced by test_interval_new.py (see #16316, #16386)
501510
def test_get_indexer(self):
502511
actual = self.index.get_indexer([-1, 0, 0.5, 1, 1.5, 2, 3])
@@ -544,6 +553,16 @@ def test_get_indexer_subintervals(self):
544553
expected = np.array([0, 0, 0], dtype='intp')
545554
tm.assert_numpy_array_equal(actual, expected)
546555

556+
# Make consistent with test_interval_new.py (see #16316, #16386)
557+
@pytest.mark.parametrize('item', [
558+
[3], np.arange(1, 5), [Interval(1, 4)], interval_range(1, 4)])
559+
def test_get_indexer_length_one(self, item, closed):
560+
# GH 17284
561+
index = IntervalIndex.from_tuples([(0, 5)], closed=closed)
562+
result = index.get_indexer(item)
563+
expected = np.array([0] * len(item), dtype='intp')
564+
tm.assert_numpy_array_equal(result, expected)
565+
547566
# To be removed, replaced by test_interval_new.py (see #16316, #16386)
548567
def test_contains(self):
549568
# Only endpoints are valid.

0 commit comments

Comments
 (0)