-
-
Notifications
You must be signed in to change notification settings - Fork 19.1k
New Interval / IntervalIndex behavior spec #16386
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
18c76f4
ddc508c
a1c3e7a
557d701
7d28038
ff1fbf2
aadfdcd
c7f6fb8
1379b08
80ebeb3
fef3187
e3a12fa
06a2835
08bd9e4
6381744
b346af7
ccd23aa
ac818f9
4a10007
e549c3d
d5a8287
0e50729
2c953b6
08d315c
9f905a8
e1eeb59
4c54f33
ca04cb2
bfaefef
ce5074a
4c5496e
33938d6
7f4c5e5
0aaaddf
a44c926
4cef040
66486d0
c0dfef8
5301dd5
57c9ba7
4cbbf2d
6126662
dc00af6
604d48d
10c9177
c8be3e6
93f1742
3464883
06484f5
e82ae33
6834c9a
33ebe1b
be050d6
1cc8004
930da2b
2e01d28
5c000a0
96c978a
ae03d01
518d16e
f530637
d90d310
acefcb0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -348,6 +348,109 @@ def test_get_loc_value(self): | |
idx = IntervalIndex.from_arrays([0, 2], [1, 3]) | ||
pytest.raises(KeyError, idx.get_loc, 1.5) | ||
|
||
@pytest.mark.xfail(reason="new indexing tests for issue 16316") | ||
def test_get_loc_value(self): | ||
|
||
right = IntervalIndex.from_tuples([(0, 1), (2, 3)], closed='right') | ||
|
||
pytest.raises(KeyError, right.get_loc(-0.5) ) | ||
pytest.raises(KeyError, right.get_loc(0) ) | ||
assert right.get_loc(0.5) == 0 | ||
|
||
assert right.get_loc(1) == 0 | ||
pytest.raises(KeyError, right.get_loc(1.5) ) | ||
pytest.raises(KeyError, right.get_loc(2) ) | ||
assert right.get_loc(2.5) == 1 | ||
assert right.get_loc(3) == 1 | ||
pytest.raises(KeyError, right.get_loc(3.5) ) | ||
|
||
assert right.get_loc(Interval(0, 1, closed='right')) == 0 | ||
pytest.raises(KeyError, right.get_loc(Interval(1, 2, closed='right')) ) | ||
assert right.get_loc(Interval(2, 3, closed='right')) == 1 | ||
pytest.raises(KeyError, right.get_loc(Interval(3, 4, closed='right')) ) | ||
pytest.raises(KeyError, right.get_loc(Interval(0, 2, closed='right')) ) | ||
pytest.raises(KeyError, right.get_loc(Interval(2.5, 3, closed='right')) ) | ||
|
||
pytest.raises(KeyError, right.get_loc(Interval(0, 1, closed='left')) ) | ||
pytest.raises(KeyError, right.get_loc(Interval(1, 2, closed='left')) ) | ||
pytest.raises(KeyError, right.get_loc(Interval(2, 3, closed='left')) ) | ||
pytest.raises(KeyError, right.get_loc(Interval(3, 4, closed='left')) ) | ||
pytest.raises(KeyError, right.get_loc(Interval(0, 2, closed='left')) ) | ||
pytest.raises(KeyError, right.get_loc(Interval(2.5, 3, closed='left')) ) | ||
|
||
pytest.raises(KeyError, right.get_loc(Interval(0, 1, closed='both')) ) | ||
pytest.raises(KeyError, right.get_loc(Interval(1, 2, closed='both')) ) | ||
pytest.raises(KeyError, right.get_loc(Interval(2, 3, closed='both')) ) | ||
pytest.raises(KeyError, right.get_loc(Interval(3, 4, closed='both')) ) | ||
pytest.raises(KeyError, right.get_loc(Interval(0, 2, closed='both')) ) | ||
pytest.raises(KeyError, right.get_loc(Interval(2.5, 3, closed='both')) ) | ||
|
||
left = IntervalIndex.from_tuples([(0, 1), (2, 3)], closed='left') | ||
|
||
|
||
pytest.raises(KeyError, left.get_loc(-0.5) ) | ||
assert left.get_loc(0) == 0 | ||
assert left.get_loc(0.5) == 0 | ||
pytest.raises(KeyError, left.get_loc(1) ) | ||
pytest.raises(KeyError, left.get_loc(1.5) ) | ||
assert left.get_loc(2) == 1 | ||
assert left.get_loc(2.5) == 1 | ||
pytest.raises(KeyError, left.get_loc(3) ) | ||
pytest.raises(KeyError, left.get_loc(3.5) ) | ||
|
||
pytest.raises(KeyError, left.get_loc(Interval(0, 1, closed='right')) ) | ||
pytest.raises(KeyError, left.get_loc(Interval(1, 2, closed='right')) ) | ||
pytest.raises(KeyError, left.get_loc(Interval(2, 3, closed='right')) ) | ||
pytest.raises(KeyError, left.get_loc(Interval(3, 4, closed='right')) ) | ||
pytest.raises(KeyError, left.get_loc(Interval(0, 2, closed='right')) ) | ||
pytest.raises(KeyError, left.get_loc(Interval(2.5, 3, closed='right')) ) | ||
|
||
assert left.get_loc(Interval(0, 1, closed='left')) == 0 | ||
pytest.raises(KeyError, left.get_loc(Interval(1, 2, closed='left')) ) | ||
assert left.get_loc(Interval(2, 3, closed='left')) == 1 | ||
pytest.raises(KeyError, left.get_loc(Interval(3, 4, closed='left')) ) | ||
pytest.raises(KeyError, left.get_loc(Interval(0, 2, closed='left')) ) | ||
pytest.raises(KeyError, left.get_loc(Interval(2.5, 3, closed='left')) ) | ||
|
||
pytest.raises(KeyError, left.get_loc(Interval(0, 1, closed='both')) ) | ||
pytest.raises(KeyError, left.get_loc(Interval(1, 2, closed='both')) ) | ||
pytest.raises(KeyError, left.get_loc(Interval(2, 3, closed='both')) ) | ||
pytest.raises(KeyError, left.get_loc(Interval(3, 4, closed='both')) ) | ||
pytest.raises(KeyError, left.get_loc(Interval(0, 2, closed='both')) ) | ||
pytest.raises(KeyError, left.get_loc(Interval(2.5, 3, closed='both')) ) | ||
|
||
both = IntervalIndex.from_tuples([(0, 1), (2, 3)], closed='both') | ||
|
||
pytest.raises(KeyError, both.get_loc(-0.5) ) | ||
assert both.get_loc(0) == 0 | ||
assert both.get_loc(0.5) == 0 | ||
assert both.get_loc(1) == 0 | ||
pytest.raises(KeyError, both.get_loc(1.5) ) | ||
assert both.get_loc(2) == 1 | ||
assert both.get_loc(2.5) == 1 | ||
assert both.get_loc(3) == 1 | ||
pytest.raises(KeyError, both.get_loc(3.5) ) | ||
|
||
pytest.raises(KeyError, both.get_loc(Interval(0, 1, closed='right')) ) | ||
pytest.raises(KeyError, both.get_loc(Interval(1, 2, closed='right')) ) | ||
pytest.raises(KeyError, both.get_loc(Interval(2, 3, closed='right')) ) | ||
pytest.raises(KeyError, both.get_loc(Interval(3, 4, closed='right')) ) | ||
pytest.raises(KeyError, both.get_loc(Interval(0, 2, closed='right')) ) | ||
pytest.raises(KeyError, both.get_loc(Interval(2.5, 3, closed='right')) ) | ||
|
||
pytest.raises(KeyError, both.get_loc(Interval(0, 1, closed='left')) ) | ||
pytest.raises(KeyError, both.get_loc(Interval(1, 2, closed='left')) ) | ||
pytest.raises(KeyError, both.get_loc(Interval(2, 3, closed='left')) ) | ||
pytest.raises(KeyError, both.get_loc(Interval(3, 4, closed='left')) ) | ||
pytest.raises(KeyError, both.get_loc(Interval(0, 2, closed='left')) ) | ||
pytest.raises(KeyError, both.get_loc(Interval(2.5, 3, closed='left')) ) | ||
|
||
assert both.get_loc(Interval(0, 1, closed='both')) == 0 | ||
pytest.raises(KeyError, both.get_loc(Interval(1, 2, closed='both')) ) | ||
assert both.get_loc(Interval(2, 3, closed='both')) == 1 | ||
pytest.raises(KeyError, both.get_loc(Interval(3, 4, closed='both')) ) | ||
pytest.raises(KeyError, both.get_loc(Interval(0, 2, closed='both')) ) | ||
pytest.raises(KeyError, both.get_loc(Interval(2.5, 3, closed='both')) ) | ||
|
||
|
||
def slice_locs_cases(self, breaks): | ||
# TODO: same tests for more index types | ||
index = IntervalIndex.from_breaks([0, 1, 2], closed='right') | ||
|
@@ -491,6 +594,188 @@ def testcontains(self): | |
assert not i.contains(20) | ||
assert not i.contains(-20) | ||
|
||
|
||
@pytest.mark.xfail(reason="new indexing tests for issue 16316") | ||
|
||
def test_interval_covers(self): | ||
|
||
# class Interval: | ||
# def covers(self, other: Interval) -> bool | ||
|
||
# def covers(self, other: IntervalIndex) -> IntegerArray1D | ||
|
||
assert Interval(1, 3).covers(Interval(1.5, 2.5)) | ||
|
||
assert Interval(1, 3).covers(Interval(1, 2)) | ||
assert Interval(1, 3).covers(Interval(2, 3)) | ||
assert not Interval(1, 3).covers(Interval(0.5, 2.5)) | ||
assert not Interval(1, 3).covers(Interval(1.5, 3.5)) | ||
|
||
|
||
assert Interval(1, 3, closed='right').covers(Interval(1, 3, closed='right')) | ||
assert not Interval(1, 3, closed='right').covers(Interval(1, 3, closed='left')) | ||
|
||
assert not Interval(1, 3, closed='right').covers(Interval(1, 3, closed='both')) | ||
|
||
assert not Interval(1, 3, closed='left').covers(Interval(1, 3, closed='right')) | ||
assert Interval(1, 3, closed='left').covers(Interval(1, 3, closed='left')) | ||
assert not Interval(1, 3, closed='left').covers(Interval(1, 3, closed='both')) | ||
|
||
assert Interval(1, 3, closed='both').covers(Interval(1, 3, closed='right')) | ||
assert Interval(1, 3, closed='both').covers(Interval(1, 3, closed='left')) | ||
assert Interval(1, 3, closed='both').covers(Interval(1, 3, closed='both')) | ||
|
||
|
||
idx = IntervalIndex.from_tuples([(0, 1), (2, 3), (1, 3)]) | ||
|
||
|
||
assert Interval(1, 3, closed='right').covers(idx) == np.array([1, 2]) | ||
|
||
assert Interval(0, 3, closed='right').covers(idx) == np.array([0, 1, 2]) | ||
assert Interval(0, 2, closed='right').covers(idx) == np.array([0]) | ||
assert Interval(2, 4, closed='right').covers(idx) == np.array([1]) | ||
|
||
assert Interval(1, 3, closed='left').covers(idx) == np.array([]) | ||
assert Interval(0, 3, closed='left').covers(idx) == np.array([0]) | ||
assert Interval(0, 2, closed='left').covers(idx) == np.array([0]) | ||
assert Interval(2, 4, closed='left').covers(idx) == np.array([1]) | ||
|
||
assert Interval(1, 3, closed='both').covers(idx) == np.array([1, 2]) | ||
assert Interval(0, 5, closed='both').covers(idx) == np.array([0, 1, 2]) | ||
assert Interval(0, 2, closed='both').covers(idx) == np.array([0]) | ||
assert Interval(2, 4, closed='both').covers(idx) == np.array([1]) | ||
|
||
|
||
@pytest.mark.xfail(reason="new indexing tests for issue 16316") | ||
def test_interval_overlaps(self): | ||
|
||
# class Interval: | ||
# def overlaps(self, other: Interval) -> bool | ||
# def overlaps(self, other: IntervalIndex) -> IntegerArray1D | ||
|
||
assert Interval(1, 3).overlaps(Interval(1.5, 2.5)) | ||
assert Interval(1, 3).overlaps(Interval(1, 2)) | ||
assert Interval(1, 3).overlaps(Interval(2, 3)) | ||
assert Interval(1, 3).overlaps(Interval(0.5, 2.5)) | ||
assert Interval(1, 3).overlaps(Interval(1.5, 3.5)) | ||
|
||
assert not Interval(1, 3).overlaps(Interval(-1, 1)) | ||
assert not Interval(1, 3).overlaps(Interval(3, 5)) | ||
|
||
# right | ||
assert Interval(1, 3, closed='right').overlaps(Interval(1, 3, closed='right')) | ||
assert Interval(1, 3, closed='right').overlaps(Interval(1, 3, closed='left')) | ||
assert Interval(1, 3, closed='right').overlaps(Interval(1, 3, closed='both')) | ||
|
||
assert not Interval(1, 3, closed='right').overlaps(Interval(-1, 1, closed='right')) | ||
assert not Interval(1, 3, closed='right').overlaps(Interval(-1, 1, closed='left')) | ||
assert not Interval(1, 3, closed='right').overlaps(Interval(-1, 1, closed='both')) | ||
|
||
assert not Interval(1, 3, closed='right').overlaps(Interval(3, 5, closed='right')) | ||
assert Interval(1, 3, closed='right').overlaps(Interval(3, 5, closed='left')) | ||
assert Interval(1, 3, closed='right').overlaps(Interval(3, 5, closed='both')) | ||
|
||
# left | ||
assert Interval(1, 3, closed='left').overlaps(Interval(1, 3, closed='right')) | ||
assert Interval(1, 3, closed='left').overlaps(Interval(1, 3, closed='left')) | ||
assert Interval(1, 3, closed='left').overlaps(Interval(1, 3, closed='both')) | ||
|
||
assert not Interval(1, 3, closed='left').overlaps(Interval(-1, 1, closed='right')) | ||
assert not Interval(1, 3, closed='left').overlaps(Interval(-1, 1, closed='left')) | ||
assert not Interval(1, 3, closed='left').overlaps(Interval(-1, 1, closed='both')) | ||
|
||
assert not Interval(1, 3, closed='left').overlaps(Interval(3, 5, closed='right')) | ||
assert Interval(1, 3, closed='left').overlaps(Interval(3, 5, closed='left')) | ||
assert Interval(1, 3, closed='left').overlaps(Interval(3, 5, closed='both')) | ||
|
||
# both | ||
assert Interval(1, 3, closed='both').overlaps(Interval(1, 3, closed='right')) | ||
assert Interval(1, 3, closed='both').overlaps(Interval(1, 3, closed='left')) | ||
assert Interval(1, 3, closed='both').overlaps(Interval(1, 3, closed='both')) | ||
|
||
assert Interval(1, 3, closed='both').overlaps(Interval(-1, 1, closed='right')) | ||
assert not Interval(1, 3, closed='both').overlaps(Interval(-1, 1, closed='left')) | ||
assert Interval(1, 3, closed='both').overlaps(Interval(-1, 1, closed='both')) | ||
|
||
assert not Interval(1, 3, closed='both').overlaps(Interval(3, 5, closed='right')) | ||
assert Interval(1, 3, closed='both').overlaps(Interval(3, 5, closed='left')) | ||
assert Interval(1, 3, closed='both').overlaps(Interval(3, 5, closed='both')) | ||
|
||
idx = IntervalIndex.from_tuples([(0, 1), (2, 3), (1, 3)]) | ||
|
||
assert Interval(1, 3, closed='right').overlaps(idx) == np.array([1, 2]) | ||
assert Interval(1, 2, closed='right').overlaps(idx) == np.array([2]) | ||
assert Interval(0, 2, closed='right').overlaps(idx) == np.array([0, 2]) | ||
assert Interval(3, 4, closed='right').overlaps(idx) == np.array([]) | ||
|
||
assert Interval(1, 3, closed='left').overlaps(idx) == np.array([0, 1, 2]) | ||
assert Interval(1, 2, closed='left').overlaps(idx) == np.array([0, 2]) | ||
assert Interval(0, 2, closed='left').overlaps(idx) == np.array([0, 2]) | ||
assert Interval(3, 4, closed='left').overlaps(idx) == np.array([3]) | ||
|
||
assert Interval(1, 3, closed='both').overlaps(idx) == np.array([0, 1, 2]) | ||
assert Interval(1, 2, closed='both').overlaps(idx) == np.array([0, 2]) | ||
assert Interval(0, 2, closed='both').overlaps(idx) == np.array([0, 2]) | ||
assert Interval(3, 4, closed='both').overlaps(idx) == np.array([3]) | ||
|
||
@pytest.mark.xfail(reason="new indexing tests for issue 16316") | ||
def test_intervalIndex_covers(self): | ||
|
||
# class IntervalIndex: | ||
# def covers(self, other: Interval) -> IntegerArray1D | ||
# def covers(self, other: IntervalIndex) -> Tuple[IntegerArray1D, IntegerArray1D] | ||
|
||
idx = IntervalIndex.from_tuples([(0, 1), (2, 3), (1, 3)]) | ||
|
||
assert idx.covers(Interval(1, 3, closed='right')) == np.array([1, 2]) | ||
assert idx.covers(Interval(0, 3, closed='right')) == np.array([0, 1, 2]) | ||
assert idx.covers(Interval(0, 2, closed='right')) == np.array([0]) | ||
assert idx.covers(Interval(2, 4, closed='right')) == np.array([1]) | ||
|
||
assert idx.covers(Interval(1, 3, closed='left')) == np.array([]) | ||
assert idx.covers(Interval(0, 3, closed='left')) == np.array([0]) | ||
assert idx.covers(Interval(0, 2, closed='left')) == np.array([0]) | ||
assert idx.covers(Interval(2, 4, closed='left')) == np.array([1]) | ||
|
||
assert idx.covers(Interval(1, 3, closed='both')) == np.array([1, 2]) | ||
assert idx.covers(Interval(0, 5, closed='both')) == np.array([0, 1, 2]) | ||
assert idx.covers(Interval(0, 2, closed='both')) == np.array([0]) | ||
assert idx.covers(Interval(2, 4, closed='both')) == np.array([1]) | ||
|
||
idx1 = IntervalIndex.from_tuples([(0, 1), (2, 3), (1, 3)], closed='right') | ||
idx2 = IntervalIndex.from_tuples([(0, 1), (2, 3), (1, 3)], closed='left') | ||
idx3 = IntervalIndex.from_tuples([(0, 1), (2, 3), (1, 3)], closed='both') | ||
|
||
assert idx.covers(idx1) == (np.array([0,1,2,2]), np.array([0,1,1,2])) # note: I had to choose an arbitrary ordering. If this test fails, double check the test too... | ||
|
||
assert idx.covers(idx2) == (np.array([2]), np.array([1])) # note: I had to choose an arbitrary ordering. If this test fails, double check the test too... | ||
assert idx.covers(idx3) == (np.array([0,1,2,2]), np.array([0,1,1,2])) # note: I had to choose an arbitrary ordering. If this test fails, double check the test too... | ||
|
||
|
||
@pytest.mark.xfail(reason="new indexing tests for issue 16316") | ||
def test_intervalIndex_overlaps(self): | ||
|
||
# class IntervalIndex: | ||
# def overlaps(self, other: Interval) -> IntegerArray1D | ||
# def overlaps(self, other: IntervalIndex) -> Tuple[IntegerArray1D, IntegerArray1D] | ||
|
||
idx = IntervalIndex.from_tuples([(0, 1), (2, 3), (1, 3)]) | ||
|
||
assert idx.overlaps(Interval(1, 3, closed='right')) == np.array([1, 2]) | ||
assert idx.overlaps(Interval(1, 2, closed='right')) == np.array([2]) | ||
assert idx.overlaps(Interval(0, 2, closed='right')) == np.array([0, 2]) | ||
assert idx.overlaps(Interval(3, 4, closed='right')) == np.array([]) | ||
|
||
assert idx.overlaps(Interval(1, 3, closed='left')) == np.array([0, 1, 2]) | ||
assert idx.overlaps(Interval(1, 2, closed='left')) == np.array([0, 2]) | ||
assert idx.overlaps(Interval(0, 2, closed='left')) == np.array([0, 2]) | ||
assert idx.overlaps(Interval(3, 4, closed='left')) == np.array([3]) | ||
|
||
assert idx.overlaps(Interval(1, 3, closed='both')) == np.array([0, 1, 2]) | ||
assert idx.overlaps(Interval(1, 2, closed='both')) == np.array([0, 2]) | ||
assert idx.overlaps(Interval(0, 2, closed='both')) == np.array([0, 2]) | ||
assert idx.overlaps(Interval(3, 4, closed='both')) == np.array([3]) | ||
|
||
idx1 = IntervalIndex.from_tuples([(0, 1), (2, 3), (1, 3)], closed='right') | ||
idx2 = IntervalIndex.from_tuples([(0, 1), (2, 3), (1, 3)], closed='left') | ||
idx3 = IntervalIndex.from_tuples([(0, 1), (2, 3), (1, 3)], closed='both') | ||
|
||
assert idx.overlaps(idx1) == (np.array([0,1,2,2]), np.array([0,1,1,2])) # note: I had to choose an arbitrary ordering. If this test fails, double check the test too... | ||
assert idx.overlaps(idx2) == (np.array([0,0,1,1,2,2]), np.array([0,2,1,2,1,2])) # note: I had to choose an arbitrary ordering. If this test fails, double check the test too... | ||
assert idx.overlaps(idx3) == (np.array([0,0,1,1,2,2]), np.array([0,2,1,2,1,2])) # note: I had to choose an arbitrary ordering. If this test fails, double check the test too... | ||
|
||
|
||
|
||
def test_dropna(self): | ||
|
||
expected = IntervalIndex.from_tuples([(0.0, 1.0), (1.0, 2.0)]) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't work. You need to use one of these forms:
or:
The second version is usually easier to read because you can use normal syntax, but in this case (with one argument) there might be something to be said for fitting on one line.