Skip to content

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

Merged
merged 63 commits into from
Dec 28, 2017
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
18c76f4
new interval and intervalIndex behavior spec
May 18, 2017
ddc508c
moved tests from indexing to indexes, and added new tests
May 25, 2017
a1c3e7a
first pass at @shoyer's review
May 26, 2017
557d701
quick update comments
May 26, 2017
7d28038
another quick pass
Jun 6, 2017
ff1fbf2
sanity check
Jun 6, 2017
aadfdcd
fixed one little issue.
Jun 7, 2017
c7f6fb8
fixed most of @jorisvandenbossche's review
Jun 19, 2017
1379b08
worked on 'contains'
Jun 19, 2017
80ebeb3
remove covers and overlaps -- to be added to a separate PR
Jun 19, 2017
fef3187
take back changes involving .contains() and __contains__
Jun 20, 2017
e3a12fa
some updates discussed
Jun 22, 2017
06a2835
quick thought...
Jun 22, 2017
08bd9e4
tiny update
Jun 29, 2017
6381744
An update to get_indexer behavior
Jul 6, 2017
b346af7
update slice locs behavior
Jul 6, 2017
ccd23aa
remove tests flagged for removal.
Jul 14, 2017
ac818f9
left side of interval must be <= right side
Jul 17, 2017
4a10007
move to throwing errors for slice locs with overlapping stuff
Jul 17, 2017
e549c3d
compress test cases
Jul 17, 2017
d5a8287
Change to InvalidIndexError
Jul 17, 2017
0e50729
compressing tests even more
Jul 17, 2017
2c953b6
some lint issues
Jul 17, 2017
08d315c
I believe all the test cases are complete.
Jul 18, 2017
9f905a8
autopep
Jul 18, 2017
e1eeb59
more pep8
Jul 18, 2017
4c54f33
remove some stuff
Jul 18, 2017
ca04cb2
tiny update
Jul 18, 2017
bfaefef
update get_indexer_non_unique tests
Jul 26, 2017
ce5074a
autopep
Jul 26, 2017
4c5496e
hopefully this is valid python
Aug 3, 2017
33938d6
Merge remote-tracking branch 'pandas-dev/master'
Sep 15, 2017
7f4c5e5
a couple updates, and a bug fix
Sep 15, 2017
0aaaddf
oops
Sep 15, 2017
a44c926
fix some lint issues
Sep 15, 2017
4cef040
start working on the review
Sep 15, 2017
66486d0
fix some slice-locs stuff
Sep 16, 2017
c0dfef8
lint issues mostly
Sep 16, 2017
5301dd5
try to satisfy pep
Sep 16, 2017
57c9ba7
for some reason that didn't make PEP happy
Sep 16, 2017
4cbbf2d
pep
Sep 16, 2017
6126662
parameterize and add a couple comments.
Sep 25, 2017
dc00af6
hopefully this works.
Sep 26, 2017
604d48d
Merge remote-tracking branch 'pandas-dev/master'
Sep 26, 2017
10c9177
fix merge conflicts
Sep 26, 2017
c8be3e6
parametrize a little bit more
jorisvandenbossche Sep 29, 2017
93f1742
remove _updated_behaviour from test name + PEP8 (unused imports)
jorisvandenbossche Sep 29, 2017
3464883
update loc tests
jorisvandenbossche Sep 30, 2017
06484f5
Merge branch 'master' into master
alexlenail Dec 19, 2017
e82ae33
update comments
Dec 20, 2017
6834c9a
Merge remote-tracking branch 'origin/master'
Dec 20, 2017
33ebe1b
worked on parameterization
Dec 20, 2017
be050d6
move xfails to top of module
Dec 21, 2017
1cc8004
minor update for pep
Dec 21, 2017
930da2b
more for pep
Dec 21, 2017
2e01d28
fix mistake
Dec 21, 2017
5c000a0
might have messed up a function signature during a previous merge. Se…
Dec 22, 2017
96c978a
formatting, potentially last bug
Dec 22, 2017
ae03d01
Merge branch 'master' into PR_TOOL_MERGE_PR_16386
jreback Dec 23, 2017
518d16e
skip interval_new tests
jreback Dec 23, 2017
f530637
lint
jreback Dec 23, 2017
d90d310
Merge branch 'master' into PR_TOOL_MERGE_PR_16386
jreback Dec 23, 2017
acefcb0
Merge branch 'master' into PR_TOOL_MERGE_PR_16386
jreback Dec 28, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
285 changes: 285 additions & 0 deletions pandas/tests/indexes/test_interval.py
Original file line number Diff line number Diff line change
Expand Up @@ -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) )
Copy link
Member

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:

pytest.raises(KeyError, right.get_loc, -0.5)

or:

with pytest.raises(KeyError):
    right.get_loc(-0.5)

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.

pytest.raises(KeyError, right.get_loc(0) )
assert right.get_loc(0.5) == 0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

per PEP8, we don't use spaces for alignment. Just a single space is preferred.

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')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is long enough for one test. Can you make this a second method, e.g., test_get_loc_vlaue_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')
Expand Down Expand Up @@ -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")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These Interval tests should actually probably go in pandas/tests/scalar/test_interval.py

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you elaborate on this a little bit? I don't see a get_loc test in that file.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interval.covers() isn't an index method (unlike IntervalIndex.covers()), so it belongs in the test file for Interval, not IntervalIndex.

def test_interval_covers(self):

# class Interval:
# def covers(self, other: Interval) -> bool
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just that I understand correctly: this is a proposal for the behaviour of a new method?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

# def covers(self, other: IntervalIndex) -> IntegerArray1D

assert Interval(1, 3).covers(Interval(1.5, 2.5))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you format those according to PEP8 a well? (it will give a bit less nice alignment for all test cases, but Travis will fail on this)

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))

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same; anytime you are doing a loop you almost always want to parametrize

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a little tidbit on why.

by putting everything in a loop, you MUST debug in order and you have no idea what currently works and what does not. parametrize basically makes little tests out of everything, so it is very easy to see where things work and where they don't. furthermore you can then debug with a very very narrow test and get to exactly what you need w/o going thru lots of steps.

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'))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

those lines are also too long for PEP8 (if you look at the travis log of the third output, all at the bottom, you can see all PEP8 violations, but I would recommend configuring your editor to also warn for this).

See http://pandas-docs.github.io/pandas-docs-travis/contributing.html#python-pep8

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer to break lines and fix style last, if that's not a problem with folks here. =)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's fine, just know that you will need to do it eventually .. :-)

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'))

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a good place to break for a new test method

idx = IntervalIndex.from_tuples([(0, 1), (2, 3), (1, 3)])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for clarity, add closed='left' or closed='right' here? (just so I don't need to remember the default


assert Interval(1, 3, closed='right').covers(idx) == np.array([1, 2])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you need to use np.testing.assert_array_equal here instead of == (remember numpy arrays overload == to do element-wise comparison).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope use

tm.assert_numpy_array_equal

we never directly use numpy comparison routines

the linter will fail if it sees np.testing fyi

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])

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should there be a test for overlapping IntervalIndex as well? (I think we said it should raise in that case, but check the discussion)

Copy link
Contributor Author

@alexlenail alexlenail Sep 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shoyer believed this case should raise. The current behavior in pandas 20.2 is essentially what you would expect from get_indexer_non_unique:

>>> index = pd.IntervalIndex.from_tuples([(0, 2), (1, 3), (2, 4)])
>>> index.get_indexer([1])
array([0])
>>> index.get_indexer([2])
array([0, 1])

What do you think I should write in here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that it should raise, so I would just add a test for it to make sure we don't lose that discussion.

@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...
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean the order of the last two entries here? I'm actually OK with this -- let's say that returning indices in lexicographically-sorted order is part of the spec.

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)])
Expand Down
Loading