def test_unique(self, closed): # unique non-overlapping idx = IntervalIndex.from_tuples( [(0, 1), (2, 3), (4, 5)], closed=closed) assert idx.is_unique is True # unique overlapping - distinct endpoints idx = IntervalIndex.from_tuples([(0, 1), (0.5, 1.5)], closed=closed) assert idx.is_unique is True # unique overlapping - shared endpoints idx = pd.IntervalIndex.from_tuples( [(1, 2), (1, 3), (2, 3)], closed=closed) assert idx.is_unique is True # unique nested idx = IntervalIndex.from_tuples([(-1, 1), (-2, 2)], closed=closed) assert idx.is_unique is True # duplicate idx = IntervalIndex.from_tuples( [(0, 1), (0, 1), (2, 3)], closed=closed) assert idx.is_unique is False # empty idx = IntervalIndex([], closed=closed) assert idx.is_unique is True
def test_constructors_errors_string(self, data): # GH 19016 left, right = data[:-1], data[1:] tuples = lzip(left, right) ivs = [Interval(l, r) for l, r in tuples] or data msg = ('category, object, and string subtypes are not supported ' 'for IntervalIndex') with tm.assert_raises_regex(TypeError, msg): IntervalIndex(ivs) with tm.assert_raises_regex(TypeError, msg): Index(ivs) with tm.assert_raises_regex(TypeError, msg): IntervalIndex.from_intervals(ivs) with tm.assert_raises_regex(TypeError, msg): IntervalIndex.from_breaks(data) with tm.assert_raises_regex(TypeError, msg): IntervalIndex.from_arrays(left, right) with tm.assert_raises_regex(TypeError, msg): IntervalIndex.from_tuples(tuples)
def test_constructors(self, data, closed, name): left, right = data[:-1], data[1:] ivs = [Interval(l, r, closed=closed) for l, r in lzip(left, right)] expected = IntervalIndex._simple_new( left=left, right=right, closed=closed, name=name) # validate expected assert expected.closed == closed assert expected.name == name assert expected.dtype.subtype == data.dtype tm.assert_index_equal(expected.left, data[:-1]) tm.assert_index_equal(expected.right, data[1:]) # validated constructors result = IntervalIndex(ivs, name=name) tm.assert_index_equal(result, expected) result = IntervalIndex.from_intervals(ivs, name=name) tm.assert_index_equal(result, expected) result = IntervalIndex.from_breaks(data, closed=closed, name=name) tm.assert_index_equal(result, expected) result = IntervalIndex.from_arrays( left, right, closed=closed, name=name) tm.assert_index_equal(result, expected) result = IntervalIndex.from_tuples( lzip(left, right), closed=closed, name=name) tm.assert_index_equal(result, expected) result = Index(ivs, name=name) assert isinstance(result, IntervalIndex) tm.assert_index_equal(result, expected) # idempotent tm.assert_index_equal(Index(expected), expected) tm.assert_index_equal(IntervalIndex(expected), expected) result = IntervalIndex.from_intervals(expected) tm.assert_index_equal(result, expected) result = IntervalIndex.from_intervals( expected.values, name=expected.name) tm.assert_index_equal(result, expected) left, right = expected.left, expected.right result = IntervalIndex.from_arrays( left, right, closed=expected.closed, name=expected.name) tm.assert_index_equal(result, expected) result = IntervalIndex.from_tuples( expected.to_tuples(), closed=expected.closed, name=expected.name) tm.assert_index_equal(result, expected) breaks = expected.left.tolist() + [expected.right[-1]] result = IntervalIndex.from_breaks( breaks, closed=expected.closed, name=expected.name) tm.assert_index_equal(result, expected)
def test_slice_locs_with_interval(self): # increasing monotonically index = IntervalIndex.from_tuples([(0, 2), (1, 3), (2, 4)]) assert index.slice_locs( start=Interval(0, 2), end=Interval(2, 4)) == (0, 3) assert index.slice_locs(start=Interval(0, 2)) == (0, 3) assert index.slice_locs(end=Interval(2, 4)) == (0, 3) assert index.slice_locs(end=Interval(0, 2)) == (0, 1) assert index.slice_locs( start=Interval(2, 4), end=Interval(0, 2)) == (2, 1) # decreasing monotonically index = IntervalIndex.from_tuples([(2, 4), (1, 3), (0, 2)]) assert index.slice_locs( start=Interval(0, 2), end=Interval(2, 4)) == (2, 1) assert index.slice_locs(start=Interval(0, 2)) == (2, 3) assert index.slice_locs(end=Interval(2, 4)) == (0, 1) assert index.slice_locs(end=Interval(0, 2)) == (0, 3) assert index.slice_locs( start=Interval(2, 4), end=Interval(0, 2)) == (0, 3) # sorted duplicates index = IntervalIndex.from_tuples([(0, 2), (0, 2), (2, 4)]) assert index.slice_locs( start=Interval(0, 2), end=Interval(2, 4)) == (0, 3) assert index.slice_locs(start=Interval(0, 2)) == (0, 3) assert index.slice_locs(end=Interval(2, 4)) == (0, 3) assert index.slice_locs(end=Interval(0, 2)) == (0, 2) assert index.slice_locs( start=Interval(2, 4), end=Interval(0, 2)) == (2, 2) # unsorted duplicates index = IntervalIndex.from_tuples([(0, 2), (2, 4), (0, 2)]) pytest.raises(KeyError, index.slice_locs( start=Interval(0, 2), end=Interval(2, 4))) pytest.raises(KeyError, index.slice_locs(start=Interval(0, 2))) assert index.slice_locs(end=Interval(2, 4)) == (0, 2) pytest.raises(KeyError, index.slice_locs(end=Interval(0, 2))) pytest.raises(KeyError, index.slice_locs( start=Interval(2, 4), end=Interval(0, 2))) # another unsorted duplicates index = IntervalIndex.from_tuples([(0, 2), (0, 2), (2, 4), (1, 3)]) assert index.slice_locs( start=Interval(0, 2), end=Interval(2, 4)) == (0, 3) assert index.slice_locs(start=Interval(0, 2)) == (0, 4) assert index.slice_locs(end=Interval(2, 4)) == (0, 3) assert index.slice_locs(end=Interval(0, 2)) == (0, 2) assert index.slice_locs( start=Interval(2, 4), end=Interval(0, 2)) == (2, 2)
def test_dropna(self): expected = IntervalIndex.from_tuples([(0.0, 1.0), (1.0, 2.0)]) ii = IntervalIndex.from_tuples([(0, 1), (1, 2), np.nan]) result = ii.dropna() tm.assert_index_equal(result, expected) ii = IntervalIndex.from_arrays([0, 1, np.nan], [1, 2, np.nan]) result = ii.dropna() tm.assert_index_equal(result, expected)
def test_get_indexer_with_ints_and_floats_multiple_queries( self, query, expected): index = IntervalIndex.from_tuples( [(0, 1), (1, 2), (3, 4)], closed='right') result = index.get_indexer(query) expected = np.array(expected, dtype='intp') tm.assert_numpy_array_equal(result, expected) index = IntervalIndex.from_tuples([(0, 2), (1, 3), (2, 4)])
def test_intersection(self, closed, sort): index = monotonic_index(0, 11, closed=closed) other = monotonic_index(5, 13, closed=closed) expected = monotonic_index(5, 11, closed=closed) result = index[::-1].intersection(other, sort=sort) if sort is None: tm.assert_index_equal(result, expected) assert tm.equalContents(result, expected) result = other[::-1].intersection(index, sort=sort) if sort is None: tm.assert_index_equal(result, expected) assert tm.equalContents(result, expected) tm.assert_index_equal(index.intersection(index, sort=sort), index) # GH 19101: empty result, same dtype other = monotonic_index(300, 314, closed=closed) expected = empty_index(dtype='int64', closed=closed) result = index.intersection(other, sort=sort) tm.assert_index_equal(result, expected) # GH 19101: empty result, different dtypes other = monotonic_index(300, 314, dtype='float64', closed=closed) result = index.intersection(other, sort=sort) tm.assert_index_equal(result, expected) # GH 26225: nested intervals index = IntervalIndex.from_tuples([(1, 2), (1, 3), (1, 4), (0, 2)]) other = IntervalIndex.from_tuples([(1, 2), (1, 3)]) expected = IntervalIndex.from_tuples([(1, 2), (1, 3)]) result = index.intersection(other) tm.assert_index_equal(result, expected) # GH 26225: duplicate element index = IntervalIndex.from_tuples([(1, 2), (1, 2), (2, 3), (3, 4)]) other = IntervalIndex.from_tuples([(1, 2), (2, 3)]) expected = IntervalIndex.from_tuples([(1, 2), (1, 2), (2, 3)]) result = index.intersection(other) tm.assert_index_equal(result, expected) # GH 26225 index = IntervalIndex.from_tuples([(0, 3), (0, 2)]) other = IntervalIndex.from_tuples([(0, 2), (1, 3)]) expected = IntervalIndex.from_tuples([(0, 2)]) result = index.intersection(other) tm.assert_index_equal(result, expected) # GH 26225: duplicate nan element index = IntervalIndex([np.nan, np.nan]) other = IntervalIndex([np.nan]) expected = IntervalIndex([np.nan]) result = index.intersection(other) tm.assert_index_equal(result, expected)
def test_constructors(self, closed, name): left, right = Index([0, 1, 2, 3]), Index([1, 2, 3, 4]) ivs = [Interval(l, r, closed=closed) for l, r in zip(left, right)] expected = IntervalIndex._simple_new( left=left, right=right, closed=closed, name=name) result = IntervalIndex(ivs, name=name) tm.assert_index_equal(result, expected) result = IntervalIndex.from_intervals(ivs, name=name) tm.assert_index_equal(result, expected) result = IntervalIndex.from_breaks( np.arange(5), closed=closed, name=name) tm.assert_index_equal(result, expected) result = IntervalIndex.from_arrays( left.values, right.values, closed=closed, name=name) tm.assert_index_equal(result, expected) result = IntervalIndex.from_tuples( zip(left, right), closed=closed, name=name) tm.assert_index_equal(result, expected) result = Index(ivs, name=name) assert isinstance(result, IntervalIndex) tm.assert_index_equal(result, expected) # idempotent tm.assert_index_equal(Index(expected), expected) tm.assert_index_equal(IntervalIndex(expected), expected) result = IntervalIndex.from_intervals( expected.values, name=expected.name) tm.assert_index_equal(result, expected) left, right = expected.left, expected.right result = IntervalIndex.from_arrays( left, right, closed=expected.closed, name=expected.name) tm.assert_index_equal(result, expected) result = IntervalIndex.from_tuples( expected.to_tuples(), closed=expected.closed, name=expected.name) tm.assert_index_equal(result, expected) breaks = expected.left.tolist() + [expected.right[-1]] result = IntervalIndex.from_breaks( breaks, closed=expected.closed, name=expected.name) tm.assert_index_equal(result, expected)
def test_monotonic_and_unique(self): self.assertTrue(self.index.is_monotonic) self.assertTrue(self.index.is_unique) idx = IntervalIndex.from_tuples([(0, 1), (0.5, 1.5)]) self.assertTrue(idx.is_monotonic) self.assertTrue(idx.is_unique) idx = IntervalIndex.from_tuples([(0, 1), (2, 3), (1, 2)]) self.assertFalse(idx.is_monotonic) self.assertTrue(idx.is_unique) idx = IntervalIndex.from_tuples([(0, 2), (0, 2)]) self.assertFalse(idx.is_unique) self.assertTrue(idx.is_monotonic)
def test_monotonic_and_unique(self): assert self.index.is_monotonic assert self.index.is_unique idx = IntervalIndex.from_tuples([(0, 1), (0.5, 1.5)]) assert idx.is_monotonic assert idx.is_unique idx = IntervalIndex.from_tuples([(0, 1), (2, 3), (1, 2)]) assert not idx.is_monotonic assert idx.is_unique idx = IntervalIndex.from_tuples([(0, 2), (0, 2)]) assert not idx.is_unique assert idx.is_monotonic
def test_constructors_empty(self, data, closed): # GH 18421 expected_dtype = getattr(data, 'dtype', np.int64) expected_values = np.array([], dtype=object) expected_index = IntervalIndex(data, closed=closed) # validate the expected index assert expected_index.empty assert expected_index.closed == closed assert expected_index.dtype.subtype == expected_dtype tm.assert_numpy_array_equal(expected_index.values, expected_values) result = IntervalIndex.from_tuples(data, closed=closed) tm.assert_index_equal(result, expected_index) tm.assert_numpy_array_equal(result.values, expected_values) result = IntervalIndex.from_breaks(data, closed=closed) tm.assert_index_equal(result, expected_index) tm.assert_numpy_array_equal(result.values, expected_values) result = IntervalIndex.from_arrays(data, data, closed=closed) tm.assert_index_equal(result, expected_index) tm.assert_numpy_array_equal(result.values, expected_values) if closed == 'right': # Can't specify closed for IntervalIndex.from_intervals result = IntervalIndex.from_intervals(data) tm.assert_index_equal(result, expected_index) tm.assert_numpy_array_equal(result.values, expected_values)
def test_constructors_nan(self, closed, data): # GH 18421 expected_values = np.array(data, dtype=object) expected_idx = IntervalIndex(data, closed=closed) # validate the expected index assert expected_idx.closed == closed tm.assert_numpy_array_equal(expected_idx.values, expected_values) result = IntervalIndex.from_tuples(data, closed=closed) tm.assert_index_equal(result, expected_idx) tm.assert_numpy_array_equal(result.values, expected_values) result = IntervalIndex.from_breaks([np.nan] + data, closed=closed) tm.assert_index_equal(result, expected_idx) tm.assert_numpy_array_equal(result.values, expected_values) result = IntervalIndex.from_arrays(data, data, closed=closed) tm.assert_index_equal(result, expected_idx) tm.assert_numpy_array_equal(result.values, expected_values) if closed == 'right': # Can't specify closed for IntervalIndex.from_intervals result = IntervalIndex.from_intervals(data) tm.assert_index_equal(result, expected_idx) tm.assert_numpy_array_equal(result.values, expected_values)
def test_qcut_nat(self, s): # GH 19768 intervals = IntervalIndex.from_tuples( [(s[0] - Nano(), s[2] - Day()), np.nan, (s[2] - Day(), s[2])]) expected = Series(Categorical(intervals, ordered=True)) result = qcut(s, 2) tm.assert_series_equal(result, expected)
def test_nonoverlapping_monotonic(self, direction, closed): tpls = [(0, 1), (2, 3), (4, 5)] if direction == 'decreasing': tpls = reversed(tpls) idx = IntervalIndex.from_tuples(tpls, closed=closed) s = Series(list('abc'), idx) for key, expected in zip(idx.left, s): if idx.closed_left: assert s[key] == expected assert s.loc[key] == expected else: with pytest.raises(KeyError): s[key] with pytest.raises(KeyError): s.loc[key] for key, expected in zip(idx.right, s): if idx.closed_right: assert s[key] == expected assert s.loc[key] == expected else: with pytest.raises(KeyError): s[key] with pytest.raises(KeyError): s.loc[key] for key, expected in zip(idx.mid, s): assert s[key] == expected assert s.loc[key] == expected
def slice_locs_cases(self, breaks): # TODO: same tests for more index types index = IntervalIndex.from_breaks([0, 1, 2], closed='right') assert index.slice_locs() == (0, 2) assert index.slice_locs(0, 1) == (0, 1) assert index.slice_locs(1, 1) == (0, 1) assert index.slice_locs(0, 2) == (0, 2) assert index.slice_locs(0.5, 1.5) == (0, 2) assert index.slice_locs(0, 0.5) == (0, 1) assert index.slice_locs(start=1) == (0, 2) assert index.slice_locs(start=1.2) == (1, 2) assert index.slice_locs(end=1) == (0, 1) assert index.slice_locs(end=1.1) == (0, 2) assert index.slice_locs(end=1.0) == (0, 1) assert index.slice_locs(-1, -1) == (0, 0) index = IntervalIndex.from_breaks([0, 1, 2], closed='neither') assert index.slice_locs(0, 1) == (0, 1) assert index.slice_locs(0, 2) == (0, 2) assert index.slice_locs(0.5, 1.5) == (0, 2) assert index.slice_locs(1, 1) == (1, 1) assert index.slice_locs(1, 2) == (1, 2) index = IntervalIndex.from_tuples([(0, 1), (2, 3), (4, 5)], closed='both') assert index.slice_locs(1, 1) == (0, 1) assert index.slice_locs(1, 2) == (0, 2)
def test_constructors_errors_tz(self, tz_left, tz_right): # GH 18537 left = date_range('2017-01-01', periods=4, tz=tz_left) right = date_range('2017-01-02', periods=4, tz=tz_right) # don't need to check IntervalIndex(...) or from_intervals, since # mixed tz are disallowed at the Interval level with pytest.raises(ValueError): IntervalIndex.from_arrays(left, right) with pytest.raises(ValueError): IntervalIndex.from_tuples(lzip(left, right)) with pytest.raises(ValueError): breaks = left.tolist() + [right[-1]] IntervalIndex.from_breaks(breaks)
def test_bins_not_overlapping_from_interval_index(): # see gh-23980 msg = "Overlapping IntervalIndex is not accepted" ii = IntervalIndex.from_tuples([(0, 10), (2, 12), (4, 14)]) with pytest.raises(ValueError, match=msg): cut([5, 6], bins=ii)
def test_non_contiguous(self, closed): index = IntervalIndex.from_tuples([(0, 1), (2, 3)], closed=closed) target = [0.5, 1.5, 2.5] actual = index.get_indexer(target) expected = np.array([0, -1, 1], dtype='intp') tm.assert_numpy_array_equal(actual, expected) assert 1.5 not in index
def test_get_indexer_with_interval_single_queries(self, query, expected): index = IntervalIndex.from_tuples( [(0, 2.5), (1, 3), (2, 4)], closed='right') result = index.get_indexer([query]) expected = np.array([expected], dtype='intp') tm.assert_numpy_array_equal(result, expected)
def test_get_indexer_with_int_and_float(self, query, expected): tuples = [(0, 1), (1, 2), (3, 4)] index = IntervalIndex.from_tuples(tuples, closed='right') result = index.get_indexer(query) expected = np.array(expected, dtype='intp') tm.assert_numpy_array_equal(result, expected)
def test_get_indexer_errors(self, tuples, closed): # IntervalIndex needs non-overlapping for uniqueness when querying index = IntervalIndex.from_tuples(tuples, closed=closed) msg = ('cannot handle overlapping indices; use ' 'IntervalIndex.get_indexer_non_unique') with pytest.raises(ValueError, match=msg): index.get_indexer([0, 2])
def test_get_indexer_non_unique_with_ints_and_floats_multiple_queries( self, query, expected): index = IntervalIndex.from_tuples( [(0, 2.5), (1, 3), (2, 4)], closed='left') result = index.get_indexer_non_unique(query) tm.assert_numpy_array_equal(result, expected)
def test_repr(self): i = IntervalIndex.from_tuples([(0, 1), (1, 2)], closed='right') expected = ("IntervalIndex(left=[0, 1]," "\n right=[1, 2]," "\n closed='right'," "\n dtype='interval[int64]')") assert repr(i) == expected i = IntervalIndex.from_tuples((Timestamp('20130101'), Timestamp('20130102')), (Timestamp('20130102'), Timestamp('20130103')), closed='right') expected = ("IntervalIndex(left=['2013-01-01', '2013-01-02']," "\n right=['2013-01-02', '2013-01-03']," "\n closed='right'," "\n dtype='interval[datetime64[ns]]')") assert repr(i) == expected
def test_override_inferred_closed(self, constructor, data, closed): # GH 19370 if isinstance(data, IntervalIndex): tuples = data.to_tuples() else: tuples = [(iv.left, iv.right) if notna(iv) else iv for iv in data] expected = IntervalIndex.from_tuples(tuples, closed=closed) result = constructor(data, closed=closed) tm.assert_index_equal(result, expected)
def test_get_indexer_with_ints_and_floats_single_queries( self, query, expected_result): index = IntervalIndex.from_tuples( [(0, 1), (1, 2), (3, 4)], closed='right') result = index.get_indexer([query]) expect = np.array([expected_result], dtype='intp') tm.assert_numpy_array_equal(result, expect)
def test_get_reindexer_datetimelike(self, arrays): # GH 20636 index = IntervalIndex.from_arrays(*arrays) tuples = [(index[0].left, index[0].left + pd.Timedelta('12H')), (index[-1].right - pd.Timedelta('12H'), index[-1].right)] target = IntervalIndex.from_tuples(tuples) result = index._get_reindexer(target) expected = np.array([0, 3], dtype='intp') tm.assert_numpy_array_equal(result, expected)
def slice_locs_decreasing_cases(self, tuples): index = IntervalIndex.from_tuples(tuples) self.assertEqual(index.slice_locs(1.5, 0.5), (1, 3)) self.assertEqual(index.slice_locs(2, 0), (1, 3)) self.assertEqual(index.slice_locs(2, 1), (1, 3)) self.assertEqual(index.slice_locs(3, 1.1), (0, 3)) self.assertEqual(index.slice_locs(3, 3), (0, 2)) self.assertEqual(index.slice_locs(3.5, 3.3), (0, 1)) self.assertEqual(index.slice_locs(1, -3), (2, 3)) self.assertEqual(*index.slice_locs(-1, -1))
def test_get_indexer_non_unique_with_int_and_float(self, query, expected): tuples = [(0, 2.5), (1, 3), (2, 4)] index = IntervalIndex.from_tuples(tuples, closed='left') result_indexer, result_missing = index.get_indexer_non_unique(query) expected_indexer = Int64Index(expected[0]) expected_missing = np.array(expected[1], dtype='intp') tm.assert_index_equal(result_indexer, expected_indexer) tm.assert_numpy_array_equal(result_missing, expected_missing)
def test_slice_locs_with_ints_and_floats_succeeds(self): # increasing non-overlapping index = IntervalIndex.from_tuples([(0, 1), (1, 2), (3, 4)]) assert index.slice_locs(0, 1) == (0, 1) assert index.slice_locs(0, 2) == (0, 2) assert index.slice_locs(0, 3) == (0, 2) assert index.slice_locs(3, 1) == (2, 1) assert index.slice_locs(3, 4) == (2, 3) assert index.slice_locs(0, 4) == (0, 3) # decreasing non-overlapping index = IntervalIndex.from_tuples([(3, 4), (1, 2), (0, 1)]) assert index.slice_locs(0, 1) == (3, 2) assert index.slice_locs(0, 2) == (3, 1) assert index.slice_locs(0, 3) == (3, 1) assert index.slice_locs(3, 1) == (1, 2) assert index.slice_locs(3, 4) == (1, 0) assert index.slice_locs(0, 4) == (3, 0)
def test_non_unique(self): idx = IntervalIndex.from_tuples([(1, 3), (3, 7)]) s = pd.Series(range(len(idx)), index=idx) result = s.loc[Interval(1, 3)] assert result == 0 result = s.loc[[Interval(1, 3)]] expected = s.iloc[0:1] tm.assert_series_equal(expected, result)
def test_slice_locs_with_interval(self): # increasing monotonically index = IntervalIndex.from_tuples([(0, 2), (1, 3), (2, 4)]) assert index.slice_locs( start=Interval(0, 2), end=Interval(2, 4)) == (0, 3) assert index.slice_locs(start=Interval(0, 2)) == (0, 3) assert index.slice_locs(end=Interval(2, 4)) == (0, 3) assert index.slice_locs(end=Interval(0, 2)) == (0, 1) assert index.slice_locs( start=Interval(2, 4), end=Interval(0, 2)) == (2, 1) # decreasing monotonically index = IntervalIndex.from_tuples([(2, 4), (1, 3), (0, 2)]) assert index.slice_locs( start=Interval(0, 2), end=Interval(2, 4)) == (2, 1) assert index.slice_locs(start=Interval(0, 2)) == (2, 3) assert index.slice_locs(end=Interval(2, 4)) == (0, 1) assert index.slice_locs(end=Interval(0, 2)) == (0, 3) assert index.slice_locs( start=Interval(2, 4), end=Interval(0, 2)) == (0, 3) # sorted duplicates index = IntervalIndex.from_tuples([(0, 2), (0, 2), (2, 4)]) assert index.slice_locs( start=Interval(0, 2), end=Interval(2, 4)) == (0, 3) assert index.slice_locs(start=Interval(0, 2)) == (0, 3) assert index.slice_locs(end=Interval(2, 4)) == (0, 3) assert index.slice_locs(end=Interval(0, 2)) == (0, 2) assert index.slice_locs( start=Interval(2, 4), end=Interval(0, 2)) == (2, 2) # unsorted duplicates index = IntervalIndex.from_tuples([(0, 2), (2, 4), (0, 2)]) with pytest.raises(KeyError): index.slice_locs(start=Interval(0, 2), end=Interval(2, 4)) with pytest.raises(KeyError): index.slice_locs(start=Interval(0, 2)) assert index.slice_locs(end=Interval(2, 4)) == (0, 2) with pytest.raises(KeyError): index.slice_locs(end=Interval(0, 2)) with pytest.raises(KeyError): index.slice_locs(start=Interval(2, 4), end=Interval(0, 2)) # another unsorted duplicates index = IntervalIndex.from_tuples([(0, 2), (0, 2), (2, 4), (1, 3)]) assert index.slice_locs( start=Interval(0, 2), end=Interval(2, 4)) == (0, 3) assert index.slice_locs(start=Interval(0, 2)) == (0, 4) assert index.slice_locs(end=Interval(2, 4)) == (0, 3) assert index.slice_locs(end=Interval(0, 2)) == (0, 2) assert index.slice_locs( start=Interval(2, 4), end=Interval(0, 2)) == (2, 2)
def test_monotonic(self, closed): # increasing non-overlapping idx = IntervalIndex.from_tuples([(0, 1), (2, 3), (4, 5)], closed=closed) assert idx.is_monotonic is True assert idx._is_strictly_monotonic_increasing is True assert idx.is_monotonic_decreasing is False assert idx._is_strictly_monotonic_decreasing is False # decreasing non-overlapping idx = IntervalIndex.from_tuples([(4, 5), (2, 3), (1, 2)], closed=closed) assert idx.is_monotonic is False assert idx._is_strictly_monotonic_increasing is False assert idx.is_monotonic_decreasing is True assert idx._is_strictly_monotonic_decreasing is True # unordered non-overlapping idx = IntervalIndex.from_tuples([(0, 1), (4, 5), (2, 3)], closed=closed) assert idx.is_monotonic is False assert idx._is_strictly_monotonic_increasing is False assert idx.is_monotonic_decreasing is False assert idx._is_strictly_monotonic_decreasing is False # increasing overlapping idx = IntervalIndex.from_tuples([(0, 2), (0.5, 2.5), (1, 3)], closed=closed) assert idx.is_monotonic is True assert idx._is_strictly_monotonic_increasing is True assert idx.is_monotonic_decreasing is False assert idx._is_strictly_monotonic_decreasing is False # decreasing overlapping idx = IntervalIndex.from_tuples([(1, 3), (0.5, 2.5), (0, 2)], closed=closed) assert idx.is_monotonic is False assert idx._is_strictly_monotonic_increasing is False assert idx.is_monotonic_decreasing is True assert idx._is_strictly_monotonic_decreasing is True # unordered overlapping idx = IntervalIndex.from_tuples([(0.5, 2.5), (0, 2), (1, 3)], closed=closed) assert idx.is_monotonic is False assert idx._is_strictly_monotonic_increasing is False assert idx.is_monotonic_decreasing is False assert idx._is_strictly_monotonic_decreasing is False # increasing overlapping shared endpoints idx = IntervalIndex.from_tuples([(1, 2), (1, 3), (2, 3)], closed=closed) assert idx.is_monotonic is True assert idx._is_strictly_monotonic_increasing is True assert idx.is_monotonic_decreasing is False assert idx._is_strictly_monotonic_decreasing is False # decreasing overlapping shared endpoints idx = IntervalIndex.from_tuples([(2, 3), (1, 3), (1, 2)], closed=closed) assert idx.is_monotonic is False assert idx._is_strictly_monotonic_increasing is False assert idx.is_monotonic_decreasing is True assert idx._is_strictly_monotonic_decreasing is True # stationary idx = IntervalIndex.from_tuples([(0, 1), (0, 1)], closed=closed) assert idx.is_monotonic is True assert idx._is_strictly_monotonic_increasing is False assert idx.is_monotonic_decreasing is True assert idx._is_strictly_monotonic_decreasing is False # empty idx = IntervalIndex([], closed=closed) assert idx.is_monotonic is True assert idx._is_strictly_monotonic_increasing is True assert idx.is_monotonic_decreasing is True assert idx._is_strictly_monotonic_decreasing is True
msg = "bins must increase monotonically" data = [0.2, 1.4, 2.5, 6.2, 9.7, 2.1] with pytest.raises(ValueError, match=msg): cut(data, [0.1, 1.5, 1, 10]) @pytest.mark.parametrize( "x, bins, expected", [ ( date_range("2017-12-31", periods=3), [Timestamp.min, Timestamp("2018-01-01"), Timestamp.max], IntervalIndex.from_tuples([ (Timestamp.min, Timestamp("2018-01-01")), (Timestamp("2018-01-01"), Timestamp.max), ]), ), ( [-1, 0, 1], np.array([np.iinfo(np.int64).min, 0, np.iinfo(np.int64).max], dtype="int64"), IntervalIndex.from_tuples([(np.iinfo(np.int64).min, 0), (0, np.iinfo(np.int64).max)]), ), ( [np.timedelta64(-1), np.timedelta64(0), np.timedelta64(1)], np.array([
def test_na_tuples(self): # tuple (NA, NA) evaluates the same as NA as an element na_tuple = [(0, 1), (np.nan, np.nan), (2, 3)] idx_na_tuple = IntervalIndex.from_tuples(na_tuple) idx_na_element = IntervalIndex.from_tuples([(0, 1), np.nan, (2, 3)]) tm.assert_index_equal(idx_na_tuple, idx_na_element)
def parse_v1(column_numbers: str) -> 'Form': """Parse 'column_numbers', or raise ValueError""" tuples = [ parse_interval(s) for s in commas.split(column_numbers.strip()) ] return Form(IntervalIndex.from_tuples(tuples, closed='both'))
def test_to_tuples(self, tuples): # GH 18756 idx = IntervalIndex.from_tuples(tuples) result = idx.to_tuples() expected = Index(com.asarray_tuplesafe(tuples)) tm.assert_index_equal(result, expected)
def test_slice_locs_with_ints_and_floats_errors(self, tuples, query): index = IntervalIndex.from_tuples(tuples) with pytest.raises(KeyError): index.slice_locs(query)