Skip to content

Commit 1ec263a

Browse files
committed
BUG: Fix IntervalIndex.to_tuples() with NA values
1 parent 9705a48 commit 1ec263a

File tree

3 files changed

+20
-1
lines changed

3 files changed

+20
-1
lines changed

doc/source/whatsnew/v0.22.0.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ Conversion
263263
- Adding a ``Period`` object to a ``datetime`` or ``Timestamp`` object will now correctly raise a ``TypeError`` (:issue:`17983`)
264264
- Fixed a bug where ``FY5253`` date offsets could incorrectly raise an ``AssertionError`` in arithmetic operatons (:issue:`14774`)
265265
- Bug in :meth:`Index.astype` with a categorical dtype where the resultant index is not converted to a :class:`CategoricalIndex` for all types of index (:issue:`18630`)
266+
- Bug in ``IntervalIndex.to_tuples()`` where NA values are returned as a tuple of NA values instead of the NA value itself (:issue:`18756`)
266267

267268

268269
Indexing

pandas/core/indexes/interval.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,11 @@ def from_tuples(cls, data, closed='right', name=None, copy=False):
546546

547547
def to_tuples(self):
548548
"""Return an Index of tuples of the form (left, right)"""
549-
return Index(_asarray_tuplesafe(zip(self.left, self.right)))
549+
tuples = _asarray_tuplesafe(zip(self.left, self.right))
550+
if self.hasnans:
551+
# GH 18756
552+
tuples = np.where(~self._isnan, tuples, np.nan)
553+
return Index(tuples)
550554

551555
@cache_readonly
552556
def _multiindex(self):

pandas/tests/indexes/test_interval.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
Interval, IntervalIndex, Index, isna, notna, interval_range, Timestamp,
88
Timedelta, compat, date_range, timedelta_range, DateOffset)
99
from pandas.compat import lzip
10+
from pandas.core.common import _asarray_tuplesafe
1011
from pandas.tseries.offsets import Day
1112
from pandas._libs.interval import IntervalTree
1213
from pandas.tests.indexes.common import Base
@@ -1072,6 +1073,19 @@ def test_is_non_overlapping_monotonic(self, closed):
10721073
idx = IntervalIndex.from_breaks(range(4), closed=closed)
10731074
assert idx.is_non_overlapping_monotonic is True
10741075

1076+
@pytest.mark.parametrize('tuples', [
1077+
lzip(range(10), range(1, 11)),
1078+
lzip(range(10), range(1, 11)) + [np.nan],
1079+
lzip(date_range('20170101', periods=10),
1080+
date_range('20170101', periods=10)),
1081+
[np.nan] + lzip(date_range('20170101', periods=10),
1082+
date_range('20170101', periods=10))])
1083+
def test_to_tuples(self, tuples):
1084+
# GH 18756
1085+
result = IntervalIndex.from_tuples(tuples).to_tuples()
1086+
expected = Index(_asarray_tuplesafe(tuples))
1087+
tm.assert_index_equal(result, expected)
1088+
10751089

10761090
class TestIntervalRange(object):
10771091

0 commit comments

Comments
 (0)