Skip to content

Commit d80cb61

Browse files
jschendelvictor
authored and
victor
committed
ENH: Add set_closed method to IntervalIndex (pandas-dev#21711)
1 parent 268a3a6 commit d80cb61

File tree

4 files changed

+55
-0
lines changed

4 files changed

+55
-0
lines changed

doc/source/api.rst

+1
Original file line numberDiff line numberDiff line change
@@ -1642,6 +1642,7 @@ IntervalIndex Components
16421642
IntervalIndex.is_non_overlapping_monotonic
16431643
IntervalIndex.get_loc
16441644
IntervalIndex.get_indexer
1645+
IntervalIndex.set_closed
16451646

16461647

16471648
.. _api.multiindex:

doc/source/whatsnew/v0.24.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ Other Enhancements
4141
(:issue:`21627`)
4242
- New method :meth:`HDFStore.walk` will recursively walk the group hierarchy of an HDF5 file (:issue:`10932`)
4343
- :meth:`Series.nlargest`, :meth:`Series.nsmallest`, :meth:`DataFrame.nlargest`, and :meth:`DataFrame.nsmallest` now accept the value ``"all"`` for the ``keep` argument. This keeps all ties for the nth largest/smallest value (:issue:`16818`)
44+
- :class:`IntervalIndex` has gained the :meth:`~IntervalIndex.set_closed` method to change the existing ``closed`` value (:issue:`21670`)
4445
-
4546

4647
.. _whatsnew_0240.api_breaking:

pandas/core/indexes/interval.py

+36
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ class IntervalIndex(IntervalMixin, Index):
180180
from_tuples
181181
get_indexer
182182
get_loc
183+
set_closed
183184
184185
Examples
185186
---------
@@ -708,6 +709,41 @@ def closed(self):
708709
"""
709710
return self._closed
710711

712+
def set_closed(self, closed):
713+
"""
714+
Return an IntervalIndex identical to the current one, but closed on the
715+
specified side
716+
717+
.. versionadded:: 0.24.0
718+
719+
Parameters
720+
----------
721+
closed : {'left', 'right', 'both', 'neither'}
722+
Whether the intervals are closed on the left-side, right-side, both
723+
or neither.
724+
725+
Returns
726+
-------
727+
new_index : IntervalIndex
728+
729+
Examples
730+
--------
731+
>>> index = pd.interval_range(0, 3)
732+
>>> index
733+
IntervalIndex([(0, 1], (1, 2], (2, 3]]
734+
closed='right',
735+
dtype='interval[int64]')
736+
>>> index.set_closed('both')
737+
IntervalIndex([[0, 1], [1, 2], [2, 3]]
738+
closed='both',
739+
dtype='interval[int64]')
740+
"""
741+
if closed not in _VALID_CLOSED:
742+
msg = "invalid option for 'closed': {closed}"
743+
raise ValueError(msg.format(closed=closed))
744+
745+
return self._shallow_copy(closed=closed)
746+
711747
@property
712748
def length(self):
713749
"""

pandas/tests/indexes/interval/test_interval.py

+17
Original file line numberDiff line numberDiff line change
@@ -977,3 +977,20 @@ def test_to_tuples_na(self, tuples, na_tuple):
977977
assert all(isna(x) for x in result_na)
978978
else:
979979
assert isna(result_na)
980+
981+
@pytest.mark.parametrize('new_closed', [
982+
'left', 'right', 'both', 'neither'])
983+
def test_set_closed(self, name, closed, new_closed):
984+
# GH 21670
985+
index = interval_range(0, 5, closed=closed, name=name)
986+
result = index.set_closed(new_closed)
987+
expected = interval_range(0, 5, closed=new_closed, name=name)
988+
tm.assert_index_equal(result, expected)
989+
990+
@pytest.mark.parametrize('bad_closed', ['foo', 10, 'LEFT', True, False])
991+
def test_set_closed_errors(self, bad_closed):
992+
# GH 21670
993+
index = interval_range(0, 5)
994+
msg = "invalid option for 'closed': {closed}".format(closed=bad_closed)
995+
with tm.assert_raises_regex(ValueError, msg):
996+
index.set_closed(bad_closed)

0 commit comments

Comments
 (0)