Skip to content

Commit 4904ac0

Browse files
author
tp
committed
IntervalIndex.get_loc can now look for exact matches only
1 parent 6ba65ca commit 4904ac0

File tree

3 files changed

+22
-2
lines changed

3 files changed

+22
-2
lines changed

doc/source/whatsnew/v0.23.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ Other API Changes
313313
- :func:`DatetimeIndex.shift` and :func:`TimedeltaIndex.shift` will now raise ``NullFrequencyError`` (which subclasses ``ValueError``, which was raised in older versions) when the index object frequency is ``None`` (:issue:`19147`)
314314
- Addition and subtraction of ``NaN`` from a :class:`Series` with ``dtype='timedelta64[ns]'`` will raise a ``TypeError` instead of treating the ``NaN`` as ``NaT`` (:issue:`19274`)
315315
- Set operations (union, difference...) on :class:`IntervalIndex` with incompatible index types will now raise a ``TypeError`` rather than a ``ValueError`` (:issue:`19329`)
316+
- :meth:`IntervalIndex.get_loc` can now find exact matches only by setting ``method='exact'`` (:issue:`19349`)
316317

317318
.. _whatsnew_0230.deprecations:
318319

pandas/core/indexes/interval.py

+13-2
Original file line numberDiff line numberDiff line change
@@ -837,7 +837,7 @@ def _maybe_cast_indexed(self, key):
837837
return key
838838

839839
def _check_method(self, method):
840-
if method is None:
840+
if method in {None, 'exact'}:
841841
return
842842

843843
if method in ['bfill', 'backfill', 'pad', 'ffill', 'nearest']:
@@ -911,8 +911,9 @@ def get_loc(self, key, method=None):
911911
Parameters
912912
----------
913913
key : label
914-
method : {None}, optional
914+
method : {None, 'exact'}, optional
915915
* default: matches where the label is within an interval only.
916+
* exact: exact matches only.
916917
917918
Returns
918919
-------
@@ -940,12 +941,22 @@ def get_loc(self, key, method=None):
940941
>>> overlapping_index = pd.IntervalIndex.from_intervals([i2, i3])
941942
>>> overlapping_index.get_loc(1.5)
942943
array([0, 1], dtype=int64)
944+
945+
If you want to find exact matches only, use ``method='exact'``:
946+
947+
>>> index.get_loc(i1, method='exact')
948+
0
949+
>>> index.get_loc(pd.Interval(0,2), method='exact')
950+
KeyError: Interval(0,2)
943951
"""
944952
self._check_method(method)
945953

946954
original_key = key
947955
key = self._maybe_cast_indexed(key)
948956

957+
if method == 'exact':
958+
return super()._engine.get_loc(key)
959+
949960
if self.is_non_overlapping_monotonic:
950961
if isinstance(key, Interval):
951962
left = self._maybe_cast_slice_bound(key.left, 'left', None)

pandas/tests/indexes/interval/test_interval.py

+8
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,10 @@ def test_get_loc_value(self):
666666
idx = IntervalIndex.from_arrays([0, 2], [1, 3])
667667
pytest.raises(KeyError, idx.get_loc, 1.5)
668668

669+
# GH19349
670+
with pytest.raises(KeyError):
671+
self.index.get_loc(0.5, method='exact')
672+
669673
# To be removed, replaced by test_interval_new.py (see #16316, #16386)
670674
def slice_locs_cases(self, breaks):
671675
# TODO: same tests for more index types
@@ -739,6 +743,10 @@ def test_get_loc_interval(self):
739743
pytest.raises(KeyError, self.index.get_loc, Interval(2, 3))
740744
pytest.raises(KeyError, self.index.get_loc,
741745
Interval(-1, 0, 'left'))
746+
# GH19349
747+
assert self.index.get_loc(Interval(0, 1), method='exact') == 0
748+
with pytest.raises(KeyError):
749+
self.index.get_loc(Interval(0, 0.5), method='exact')
742750

743751
# To be removed, replaced by test_interval_new.py (see #16316, #16386)
744752
def test_get_indexer(self):

0 commit comments

Comments
 (0)