From ec4c87faac046aea763a42de24e1b745c06e7c78 Mon Sep 17 00:00:00 2001 From: Alexander Lenail Date: Mon, 2 Apr 2018 17:11:04 -0400 Subject: [PATCH 1/2] setup changes. --- .../tests/indexes/interval/test_interval.py | 455 +++++++++++------- .../indexes/interval/test_interval_new.py | 315 ------------ .../tests/indexing/interval/test_interval.py | 199 ++++++-- .../indexing/interval/test_interval_new.py | 247 ---------- 4 files changed, 440 insertions(+), 776 deletions(-) delete mode 100644 pandas/tests/indexes/interval/test_interval_new.py delete mode 100644 pandas/tests/indexing/interval/test_interval_new.py diff --git a/pandas/tests/indexes/interval/test_interval.py b/pandas/tests/indexes/interval/test_interval.py index 71a6f78125004..2df8a91a5505c 100644 --- a/pandas/tests/indexes/interval/test_interval.py +++ b/pandas/tests/indexes/interval/test_interval.py @@ -31,6 +31,13 @@ def setup_method(self, method): [(0, 1), np.nan, (1, 2)]) self.indices = dict(intervalIndex=tm.makeIntervalIndex(10)) + def _compare_tuple_of_numpy_array(self, result, expected): + lidx, ridx = result + lidx_expected, ridx_expected = expected + + tm.assert_numpy_array_equal(lidx, lidx_expected) + tm.assert_numpy_array_equal(ridx, ridx_expected) + def create_index(self, closed='right'): return IntervalIndex.from_breaks(range(11), closed=closed) @@ -400,184 +407,300 @@ def test_get_item(self, closed): closed=closed) tm.assert_index_equal(result, expected) - # To be removed, replaced by test_interval_new.py (see #16316, #16386) - def test_get_loc_value(self): - pytest.raises(KeyError, self.index.get_loc, 0) - assert self.index.get_loc(0.5) == 0 - assert self.index.get_loc(1) == 0 - assert self.index.get_loc(1.5) == 1 - assert self.index.get_loc(2) == 1 - pytest.raises(KeyError, self.index.get_loc, -1) - pytest.raises(KeyError, self.index.get_loc, 3) - - idx = IntervalIndex.from_tuples([(0, 2), (1, 3)]) - assert idx.get_loc(0.5) == 0 - assert idx.get_loc(1) == 0 - tm.assert_numpy_array_equal(idx.get_loc(1.5), - np.array([0, 1], dtype='int64')) - tm.assert_numpy_array_equal(np.sort(idx.get_loc(2)), - np.array([0, 1], dtype='int64')) - assert idx.get_loc(3) == 1 - pytest.raises(KeyError, idx.get_loc, 3.5) - - idx = IntervalIndex.from_arrays([0, 2], [1, 3]) - pytest.raises(KeyError, idx.get_loc, 1.5) - - # To be removed, replaced by test_interval_new.py (see #16316, #16386) - 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') + @pytest.mark.parametrize("idx_side", ['right', 'left', 'both', 'neither']) + @pytest.mark.parametrize("side", ['right', 'left', 'both', 'neither']) + def test_get_loc_interval(self, idx_side, side): + + idx = IntervalIndex.from_tuples([(0, 1), (2, 3)], closed=idx_side) + + for bound in [[0, 1], [1, 2], [2, 3], [3, 4], + [0, 2], [2.5, 3], [-1, 4]]: + # if get_loc is supplied an interval, it should only search + # for exact matches, not overlaps or covers, else KeyError. + if idx_side == side: + if bound == [0, 1]: + assert idx.get_loc(Interval(0, 1, closed=side)) == 0 + elif bound == [2, 3]: + assert idx.get_loc(Interval(2, 3, closed=side)) == 1 + else: + with pytest.raises(KeyError): + idx.get_loc(Interval(*bound, closed=side)) + else: + with pytest.raises(KeyError): + idx.get_loc(Interval(*bound, closed=side)) + + @pytest.mark.parametrize("idx_side", ['right', 'left', 'both', 'neither']) + @pytest.mark.parametrize("scalar", [-0.5, 0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5]) + def test_get_loc_scalar(self, idx_side, scalar): + + # correct = {side: {query: answer}}. + # If query is not in the dict, that query should raise a KeyError + correct = {'right': {0.5: 0, 1: 0, 2.5: 1, 3: 1}, + 'left': {0: 0, 0.5: 0, 2: 1, 2.5: 1}, + 'both': {0: 0, 0.5: 0, 1: 0, 2: 1, 2.5: 1, 3: 1}, + 'neither': {0.5: 0, 2.5: 1}} + + idx = IntervalIndex.from_tuples([(0, 1), (2, 3)], closed=idx_side) + + # if get_loc is supplied a scalar, it should return the index of + # the interval which contains the scalar, or KeyError. + if scalar in correct[idx_side].keys(): + assert idx.get_loc(scalar) == correct[idx_side][scalar] + else: + pytest.raises(KeyError, idx.get_loc, scalar) + + 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_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.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) - - # To be removed, replaced by test_interval_new.py (see #16316, #16386) - def test_slice_locs_int64(self): - self.slice_locs_cases([0, 1, 2]) - - # To be removed, replaced by test_interval_new.py (see #16316, #16386) - def test_slice_locs_float64(self): - self.slice_locs_cases([0.0, 1.0, 2.0]) - - # To be removed, replaced by test_interval_new.py (see #16316, #16386) - def slice_locs_decreasing_cases(self, tuples): - index = IntervalIndex.from_tuples(tuples) - assert index.slice_locs(1.5, 0.5) == (1, 3) - assert index.slice_locs(2, 0) == (1, 3) - assert index.slice_locs(2, 1) == (1, 3) - assert index.slice_locs(3, 1.1) == (0, 3) - assert index.slice_locs(3, 3) == (0, 2) - assert index.slice_locs(3.5, 3.3) == (0, 1) - assert index.slice_locs(1, -3) == (2, 3) - - slice_locs = index.slice_locs(-1, -1) - assert slice_locs[0] == slice_locs[1] - - # To be removed, replaced by test_interval_new.py (see #16316, #16386) - def test_slice_locs_decreasing_int64(self): - self.slice_locs_cases([(2, 4), (1, 3), (0, 2)]) - - # To be removed, replaced by test_interval_new.py (see #16316, #16386) - def test_slice_locs_decreasing_float64(self): - self.slice_locs_cases([(2., 4.), (1., 3.), (0., 2.)]) - - # To be removed, replaced by test_interval_new.py (see #16316, #16386) - def test_slice_locs_fails(self): - index = IntervalIndex.from_tuples([(1, 2), (0, 1), (2, 3)]) - with pytest.raises(KeyError): - index.slice_locs(1, 2) - - # To be removed, replaced by test_interval_new.py (see #16316, #16386) - def test_get_loc_interval(self): - assert self.index.get_loc(Interval(0, 1)) == 0 - assert self.index.get_loc(Interval(0, 0.5)) == 0 - assert self.index.get_loc(Interval(0, 1, 'left')) == 0 - pytest.raises(KeyError, self.index.get_loc, Interval(2, 3)) - pytest.raises(KeyError, self.index.get_loc, - Interval(-1, 0, 'left')) - - # To be removed, replaced by test_interval_new.py (see #16316, #16386) - def test_get_indexer(self): - actual = self.index.get_indexer([-1, 0, 0.5, 1, 1.5, 2, 3]) - expected = np.array([-1, -1, 0, 0, 1, 1, -1], dtype='intp') - tm.assert_numpy_array_equal(actual, expected) + 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) - actual = self.index.get_indexer(self.index) - expected = np.array([0, 1], dtype='intp') - tm.assert_numpy_array_equal(actual, expected) + # 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) + + @pytest.mark.parametrize("query", [[0, 1], [0, 2], [0, 3], + [3, 1], [3, 4], [0, 4]]) + def test_slice_locs_with_ints_and_floats_fails(self, query): - index = IntervalIndex.from_breaks([0, 1, 2], closed='left') - actual = index.get_indexer([-1, 0, 0.5, 1, 1.5, 2, 3]) - expected = np.array([-1, 0, 0, 1, 1, -1, -1], dtype='intp') - tm.assert_numpy_array_equal(actual, expected) + # increasing overlapping + index = IntervalIndex.from_tuples([(0, 2), (1, 3), (2, 4)]) + pytest.raises(KeyError, index.slice_locs, query) - actual = self.index.get_indexer(index[:1]) - expected = np.array([0], dtype='intp') - tm.assert_numpy_array_equal(actual, expected) + # decreasing overlapping + index = IntervalIndex.from_tuples([(2, 4), (1, 3), (0, 2)]) + pytest.raises(KeyError, index.slice_locs, query) + + # sorted duplicates + index = IntervalIndex.from_tuples([(0, 2), (0, 2), (2, 4)]) + pytest.raises(KeyError, index.slice_locs, query) + + # unsorted duplicates + index = IntervalIndex.from_tuples([(0, 2), (2, 4), (0, 2)]) + pytest.raises(KeyError, index.slice_locs, query) + + # another unsorted duplicates + index = IntervalIndex.from_tuples([(0, 2), (0, 2), (2, 4), (1, 3)]) + pytest.raises(KeyError, index.slice_locs, query) + + @pytest.mark.parametrize("query", [ + Interval(1, 3, closed='right'), + Interval(1, 3, closed='left'), + Interval(1, 3, closed='both'), + Interval(1, 3, closed='neither'), + Interval(1, 4, closed='right'), + Interval(0, 4, closed='right'), + Interval(1, 2, closed='right')]) + @pytest.mark.parametrize("expected_result", [1, -1, -1, -1, -1, -1, -1]) + def test_get_indexer_with_interval_single_queries( + self, query, expected_result): + + index = IntervalIndex.from_tuples( + [(0, 2.5), (1, 3), (2, 4)], closed='right') + + result = index.get_indexer([query]) + expect = np.array([expected_result], dtype='intp') + tm.assert_numpy_array_equal(result, expect) + + @pytest.mark.parametrize("query", [ + [Interval(2, 4, closed='right'), Interval(1, 3, closed='right')], + [Interval(1, 3, closed='right'), Interval(0, 2, closed='right')], + [Interval(1, 3, closed='right'), Interval(1, 3, closed='left')]]) + @pytest.mark.parametrize("expected_result", [[2, 1], [1, -1], [1, -1]]) + def test_get_indexer_with_interval_multiple_queries( + self, query, expected_result): + + index = IntervalIndex.from_tuples( + [(0, 2.5), (1, 3), (2, 4)], closed='right') + + result = index.get_indexer(query) + expect = np.array(expected_result, dtype='intp') + tm.assert_numpy_array_equal(result, expect) + + @pytest.mark.parametrize( + "query", + [-0.5, 0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5]) + @pytest.mark.parametrize( + "expected_result", + [-1, -1, 0, 0, 1, 1, -1, -1, 2, 2, -1]) + 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) + + @pytest.mark.parametrize( + "query", + [[1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 2]]) + @pytest.mark.parametrize( + "expected_result", + [[0, 1], [0, 1, -1], [0, 1, -1, 2], [0, 1, -1, 2, 1]]) + def test_get_indexer_with_ints_and_floats_multiple_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) + + index = IntervalIndex.from_tuples([(0, 2), (1, 3), (2, 4)]) + # TODO: @shoyer believes this should raise, master branch doesn't + + @pytest.mark.parametrize( + "query", + [-0.5, 0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5]) + @pytest.mark.parametrize("expected_result", [ + (Int64Index([], dtype='int64'), np.array([0])), + (Int64Index([0], dtype='int64'), np.array([])), + (Int64Index([0], dtype='int64'), np.array([])), + (Int64Index([0, 1], dtype='int64'), np.array([])), + (Int64Index([0, 1], dtype='int64'), np.array([])), + (Int64Index([0, 1, 2], dtype='int64'), np.array([])), + (Int64Index([1, 2], dtype='int64'), np.array([])), + (Int64Index([2], dtype='int64'), np.array([])), + (Int64Index([2], dtype='int64'), np.array([])), + (Int64Index([], dtype='int64'), np.array([0])), + (Int64Index([], dtype='int64'), np.array([0]))]) + def test_get_indexer_non_unique_with_ints_and_floats_single_queries( + self, query, expected_result): + + 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_result) + + @pytest.mark.parametrize( + "query", + [[1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 2]]) + @pytest.mark.parametrize("expected_result", [ + (Int64Index([0, 1, 0, 1, 2], dtype='int64'), np.array([])), + (Int64Index([0, 1, 0, 1, 2, 2], dtype='int64'), np.array([])), + (Int64Index([0, 1, 0, 1, 2, 2, -1], dtype='int64'), np.array([3])), + (Int64Index([0, 1, 0, 1, 2, 2, -1, 0, 1, 2], dtype='int64'), + np.array([3]))]) + def test_get_indexer_non_unique_with_ints_and_floats_multiple_queries( + self, query, expected_result): + + 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_result) + + # TODO we may also want to test get_indexer for the case when + # the intervals are duplicated, decreasing, non-monotonic, etc.. - actual = self.index.get_indexer(index) - expected = np.array([-1, 1], dtype='intp') - tm.assert_numpy_array_equal(actual, expected) + def test_contains(self): - # To be removed, replaced by test_interval_new.py (see #16316, #16386) - def test_get_indexer_subintervals(self): + index = IntervalIndex.from_arrays([0, 1], [1, 2], closed='right') - # TODO: is this right? - # return indexers for wholly contained subintervals - target = IntervalIndex.from_breaks(np.linspace(0, 2, 5)) - actual = self.index.get_indexer(target) - expected = np.array([0, 0, 1, 1], dtype='p') - tm.assert_numpy_array_equal(actual, expected) + # __contains__ requires perfect matches to intervals. + assert 0 not in index + assert 1 not in index + assert 2 not in index - target = IntervalIndex.from_breaks([0, 0.67, 1.33, 2]) - actual = self.index.get_indexer(target) - expected = np.array([0, 0, 1, 1], dtype='intp') - tm.assert_numpy_array_equal(actual, expected) + assert Interval(0, 1, closed='right') in index + assert Interval(0, 2, closed='right') not in index + assert Interval(0, 0.5, closed='right') not in index + assert Interval(3, 5, closed='right') not in index + assert Interval(-1, 0, closed='left') not in index + assert Interval(0, 1, closed='left') not in index + assert Interval(0, 1, closed='both') not in index - actual = self.index.get_indexer(target[[0, -1]]) - expected = np.array([0, 1], dtype='intp') - tm.assert_numpy_array_equal(actual, expected) + def test_contains_method(self): - target = IntervalIndex.from_breaks([0, 0.33, 0.67, 1], closed='left') - actual = self.index.get_indexer(target) - expected = np.array([0, 0, 0], dtype='intp') - tm.assert_numpy_array_equal(actual, expected) + index = IntervalIndex.from_arrays([0, 1], [1, 2], closed='right') - # To be removed, replaced by test_interval_new.py (see #16316, #16386) - def test_contains(self): - # Only endpoints are valid. - i = IntervalIndex.from_arrays([0, 1], [1, 2]) - - # Invalid - assert 0 not in i - assert 1 not in i - assert 2 not in i - - # Valid - assert Interval(0, 1) in i - assert Interval(0, 2) in i - assert Interval(0, 0.5) in i - assert Interval(3, 5) not in i - assert Interval(-1, 0, closed='left') not in i - - # To be removed, replaced by test_interval_new.py (see #16316, #16386) - def testcontains(self): - # can select values that are IN the range of a value - i = IntervalIndex.from_arrays([0, 1], [1, 2]) - - assert i.contains(0.1) - assert i.contains(0.5) - assert i.contains(1) - assert i.contains(Interval(0, 1)) - assert i.contains(Interval(0, 2)) - - # these overlaps completely - assert i.contains(Interval(0, 3)) - assert i.contains(Interval(1, 3)) - - assert not i.contains(20) - assert not i.contains(-20) + assert not index.contains(0) + assert index.contains(0.1) + assert index.contains(0.5) + assert index.contains(1) + + assert index.contains(Interval(0, 1), closed='right') + assert not index.contains(Interval(0, 1), closed='left') + assert not index.contains(Interval(0, 1), closed='both') + assert not index.contains(Interval(0, 2), closed='right') + + assert not index.contains(Interval(0, 3), closed='right') + assert not index.contains(Interval(1, 3), closed='right') + + assert not index.contains(20) + assert not index.contains(-20) def test_dropna(self, closed): diff --git a/pandas/tests/indexes/interval/test_interval_new.py b/pandas/tests/indexes/interval/test_interval_new.py deleted file mode 100644 index a0d11db46d316..0000000000000 --- a/pandas/tests/indexes/interval/test_interval_new.py +++ /dev/null @@ -1,315 +0,0 @@ -from __future__ import division - -import pytest -import numpy as np - -from pandas import Interval, IntervalIndex, Int64Index -import pandas.util.testing as tm - - -pytestmark = pytest.mark.skip(reason="new indexing tests for issue 16316") - - -class TestIntervalIndex(object): - - def _compare_tuple_of_numpy_array(self, result, expected): - lidx, ridx = result - lidx_expected, ridx_expected = expected - - tm.assert_numpy_array_equal(lidx, lidx_expected) - tm.assert_numpy_array_equal(ridx, ridx_expected) - - @pytest.mark.parametrize("idx_side", ['right', 'left', 'both', 'neither']) - @pytest.mark.parametrize("side", ['right', 'left', 'both', 'neither']) - def test_get_loc_interval(self, idx_side, side): - - idx = IntervalIndex.from_tuples([(0, 1), (2, 3)], closed=idx_side) - - for bound in [[0, 1], [1, 2], [2, 3], [3, 4], - [0, 2], [2.5, 3], [-1, 4]]: - # if get_loc is supplied an interval, it should only search - # for exact matches, not overlaps or covers, else KeyError. - if idx_side == side: - if bound == [0, 1]: - assert idx.get_loc(Interval(0, 1, closed=side)) == 0 - elif bound == [2, 3]: - assert idx.get_loc(Interval(2, 3, closed=side)) == 1 - else: - with pytest.raises(KeyError): - idx.get_loc(Interval(*bound, closed=side)) - else: - with pytest.raises(KeyError): - idx.get_loc(Interval(*bound, closed=side)) - - @pytest.mark.parametrize("idx_side", ['right', 'left', 'both', 'neither']) - @pytest.mark.parametrize("scalar", [-0.5, 0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5]) - def test_get_loc_scalar(self, idx_side, scalar): - - # correct = {side: {query: answer}}. - # If query is not in the dict, that query should raise a KeyError - correct = {'right': {0.5: 0, 1: 0, 2.5: 1, 3: 1}, - 'left': {0: 0, 0.5: 0, 2: 1, 2.5: 1}, - 'both': {0: 0, 0.5: 0, 1: 0, 2: 1, 2.5: 1, 3: 1}, - 'neither': {0.5: 0, 2.5: 1}} - - idx = IntervalIndex.from_tuples([(0, 1), (2, 3)], closed=idx_side) - - # if get_loc is supplied a scalar, it should return the index of - # the interval which contains the scalar, or KeyError. - if scalar in correct[idx_side].keys(): - assert idx.get_loc(scalar) == correct[idx_side][scalar] - else: - pytest.raises(KeyError, idx.get_loc, scalar) - - 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_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) - - @pytest.mark.parametrize("query", [[0, 1], [0, 2], [0, 3], - [3, 1], [3, 4], [0, 4]]) - def test_slice_locs_with_ints_and_floats_fails(self, query): - - # increasing overlapping - index = IntervalIndex.from_tuples([(0, 2), (1, 3), (2, 4)]) - pytest.raises(KeyError, index.slice_locs, query) - - # decreasing overlapping - index = IntervalIndex.from_tuples([(2, 4), (1, 3), (0, 2)]) - pytest.raises(KeyError, index.slice_locs, query) - - # sorted duplicates - index = IntervalIndex.from_tuples([(0, 2), (0, 2), (2, 4)]) - pytest.raises(KeyError, index.slice_locs, query) - - # unsorted duplicates - index = IntervalIndex.from_tuples([(0, 2), (2, 4), (0, 2)]) - pytest.raises(KeyError, index.slice_locs, query) - - # another unsorted duplicates - index = IntervalIndex.from_tuples([(0, 2), (0, 2), (2, 4), (1, 3)]) - pytest.raises(KeyError, index.slice_locs, query) - - @pytest.mark.parametrize("query", [ - Interval(1, 3, closed='right'), - Interval(1, 3, closed='left'), - Interval(1, 3, closed='both'), - Interval(1, 3, closed='neither'), - Interval(1, 4, closed='right'), - Interval(0, 4, closed='right'), - Interval(1, 2, closed='right')]) - @pytest.mark.parametrize("expected_result", [1, -1, -1, -1, -1, -1, -1]) - def test_get_indexer_with_interval_single_queries( - self, query, expected_result): - - index = IntervalIndex.from_tuples( - [(0, 2.5), (1, 3), (2, 4)], closed='right') - - result = index.get_indexer([query]) - expect = np.array([expected_result], dtype='intp') - tm.assert_numpy_array_equal(result, expect) - - @pytest.mark.parametrize("query", [ - [Interval(2, 4, closed='right'), Interval(1, 3, closed='right')], - [Interval(1, 3, closed='right'), Interval(0, 2, closed='right')], - [Interval(1, 3, closed='right'), Interval(1, 3, closed='left')]]) - @pytest.mark.parametrize("expected_result", [[2, 1], [1, -1], [1, -1]]) - def test_get_indexer_with_interval_multiple_queries( - self, query, expected_result): - - index = IntervalIndex.from_tuples( - [(0, 2.5), (1, 3), (2, 4)], closed='right') - - result = index.get_indexer(query) - expect = np.array(expected_result, dtype='intp') - tm.assert_numpy_array_equal(result, expect) - - @pytest.mark.parametrize( - "query", - [-0.5, 0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5]) - @pytest.mark.parametrize( - "expected_result", - [-1, -1, 0, 0, 1, 1, -1, -1, 2, 2, -1]) - 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) - - @pytest.mark.parametrize( - "query", - [[1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 2]]) - @pytest.mark.parametrize( - "expected_result", - [[0, 1], [0, 1, -1], [0, 1, -1, 2], [0, 1, -1, 2, 1]]) - def test_get_indexer_with_ints_and_floats_multiple_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) - - index = IntervalIndex.from_tuples([(0, 2), (1, 3), (2, 4)]) - # TODO: @shoyer believes this should raise, master branch doesn't - - @pytest.mark.parametrize( - "query", - [-0.5, 0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5]) - @pytest.mark.parametrize("expected_result", [ - (Int64Index([], dtype='int64'), np.array([0])), - (Int64Index([0], dtype='int64'), np.array([])), - (Int64Index([0], dtype='int64'), np.array([])), - (Int64Index([0, 1], dtype='int64'), np.array([])), - (Int64Index([0, 1], dtype='int64'), np.array([])), - (Int64Index([0, 1, 2], dtype='int64'), np.array([])), - (Int64Index([1, 2], dtype='int64'), np.array([])), - (Int64Index([2], dtype='int64'), np.array([])), - (Int64Index([2], dtype='int64'), np.array([])), - (Int64Index([], dtype='int64'), np.array([0])), - (Int64Index([], dtype='int64'), np.array([0]))]) - def test_get_indexer_non_unique_with_ints_and_floats_single_queries( - self, query, expected_result): - - 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_result) - - @pytest.mark.parametrize( - "query", - [[1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 2]]) - @pytest.mark.parametrize("expected_result", [ - (Int64Index([0, 1, 0, 1, 2], dtype='int64'), np.array([])), - (Int64Index([0, 1, 0, 1, 2, 2], dtype='int64'), np.array([])), - (Int64Index([0, 1, 0, 1, 2, 2, -1], dtype='int64'), np.array([3])), - (Int64Index([0, 1, 0, 1, 2, 2, -1, 0, 1, 2], dtype='int64'), - np.array([3]))]) - def test_get_indexer_non_unique_with_ints_and_floats_multiple_queries( - self, query, expected_result): - - 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_result) - - # TODO we may also want to test get_indexer for the case when - # the intervals are duplicated, decreasing, non-monotonic, etc.. - - def test_contains(self): - - index = IntervalIndex.from_arrays([0, 1], [1, 2], closed='right') - - # __contains__ requires perfect matches to intervals. - assert 0 not in index - assert 1 not in index - assert 2 not in index - - assert Interval(0, 1, closed='right') in index - assert Interval(0, 2, closed='right') not in index - assert Interval(0, 0.5, closed='right') not in index - assert Interval(3, 5, closed='right') not in index - assert Interval(-1, 0, closed='left') not in index - assert Interval(0, 1, closed='left') not in index - assert Interval(0, 1, closed='both') not in index - - def test_contains_method(self): - - index = IntervalIndex.from_arrays([0, 1], [1, 2], closed='right') - - assert not index.contains(0) - assert index.contains(0.1) - assert index.contains(0.5) - assert index.contains(1) - - assert index.contains(Interval(0, 1), closed='right') - assert not index.contains(Interval(0, 1), closed='left') - assert not index.contains(Interval(0, 1), closed='both') - assert not index.contains(Interval(0, 2), closed='right') - - assert not index.contains(Interval(0, 3), closed='right') - assert not index.contains(Interval(1, 3), closed='right') - - assert not index.contains(20) - assert not index.contains(-20) diff --git a/pandas/tests/indexing/interval/test_interval.py b/pandas/tests/indexing/interval/test_interval.py index 233fbd2c8d7be..f0f91aa75b084 100644 --- a/pandas/tests/indexing/interval/test_interval.py +++ b/pandas/tests/indexing/interval/test_interval.py @@ -86,31 +86,42 @@ def test_nonoverlapping_monotonic(self, direction, closed): assert s[key] == expected assert s.loc[key] == expected - # To be removed, replaced by test_interval_new.py (see #16316, #16386) - def test_with_interval(self): + def test_loc_with_interval(self): + + # loc with single label / list of labels: + # - Intervals: only exact matches + # - scalars: those that contain it s = self.s - expected = 0 + expected = 0 result = s.loc[Interval(0, 1)] assert result == expected - result = s[Interval(0, 1)] assert result == expected expected = s.iloc[3:5] - result = s.loc[Interval(3, 6)] + result = s.loc[[Interval(3, 4), Interval(4, 5)]] tm.assert_series_equal(expected, result) - - expected = s.iloc[3:5] - result = s.loc[[Interval(3, 6)]] + result = s[[Interval(3, 4), Interval(4, 5)]] tm.assert_series_equal(expected, result) - expected = s.iloc[3:5] - result = s.loc[[Interval(3, 5)]] - tm.assert_series_equal(expected, result) + # missing or not exact + with pytest.raises(KeyError): + s.loc[Interval(3, 5, closed='left')] + + with pytest.raises(KeyError): + s[Interval(3, 5, closed='left')] + + with pytest.raises(KeyError): + s[Interval(3, 5)] + + with pytest.raises(KeyError): + s.loc[Interval(3, 5)] + + with pytest.raises(KeyError): + s[Interval(3, 5)] - # missing with pytest.raises(KeyError): s.loc[Interval(-2, 0)] @@ -123,69 +134,161 @@ def test_with_interval(self): with pytest.raises(KeyError): s[Interval(5, 6)] - # To be removed, replaced by test_interval_new.py (see #16316, #16386) - def test_with_slices(self): + def test_loc_with_scalar(self): + + # loc with single label / list of labels: + # - Intervals: only exact matches + # - scalars: those that contain it + + s = self.s + + assert s.loc[1] == 0 + assert s.loc[1.5] == 1 + assert s.loc[2] == 1 + + # TODO with __getitem__ same rules as loc, or positional ? + # assert s[1] == 0 + # assert s[1.5] == 1 + # assert s[2] == 1 + + expected = s.iloc[1:4] + tm.assert_series_equal(expected, s.loc[[1.5, 2.5, 3.5]]) + tm.assert_series_equal(expected, s.loc[[2, 3, 4]]) + tm.assert_series_equal(expected, s.loc[[1.5, 3, 4]]) + + expected = s.iloc[[1, 1, 2, 1]] + tm.assert_series_equal(expected, s.loc[[1.5, 2, 2.5, 1.5]]) + + expected = s.iloc[2:5] + tm.assert_series_equal(expected, s.loc[s >= 2]) + + def test_loc_with_slices(self): + + # loc with slices: + # - Interval objects: only works with exact matches + # - scalars: only works for non-overlapping, monotonic intervals, + # and start/stop select location based on the interval that + # contains them: + # (slice_loc(start, stop) == (idx.get_loc(start), idx.get_loc(stop)) s = self.s # slice of interval - with pytest.raises(NotImplementedError): + + expected = s.iloc[:3] + result = s.loc[Interval(0, 1):Interval(2, 3)] + tm.assert_series_equal(expected, result) + result = s[Interval(0, 1):Interval(2, 3)] + tm.assert_series_equal(expected, result) + + expected = s.iloc[4:] + result = s.loc[Interval(3, 4):] + tm.assert_series_equal(expected, result) + result = s[Interval(3, 4):] + tm.assert_series_equal(expected, result) + + with pytest.raises(KeyError): s.loc[Interval(3, 6):] - with pytest.raises(NotImplementedError): + with pytest.raises(KeyError): s[Interval(3, 6):] - expected = s.iloc[3:5] - result = s[[Interval(3, 6)]] - tm.assert_series_equal(expected, result) + with pytest.raises(KeyError): + s.loc[Interval(3, 4, closed='left'):] + + with pytest.raises(KeyError): + s[Interval(3, 4, closed='left'):] + + # TODO with non-existing intervals ? + # s.loc[Interval(-1, 0):Interval(2, 3)] + + # slice of scalar + + expected = s.iloc[:3] + tm.assert_series_equal(expected, s.loc[:3]) + tm.assert_series_equal(expected, s.loc[:2.5]) + tm.assert_series_equal(expected, s.loc[0.1:2.5]) + + # TODO should this work? (-1 is not contained in any of the Intervals) + # tm.assert_series_equal(expected, s.loc[-1:3]) + + # TODO with __getitem__ same rules as loc, or positional ? + # tm.assert_series_equal(expected, s[:3]) + # tm.assert_series_equal(expected, s[:2.5]) + # tm.assert_series_equal(expected, s[0.1:2.5]) # slice of scalar with step != 1 - with pytest.raises(ValueError): + with pytest.raises(NotImplementedError): s[0:4:2] - # To be removed, replaced by test_interval_new.py (see #16316, #16386) - def test_with_overlaps(self): - - s = self.s - expected = s.iloc[[3, 4, 3, 4]] - result = s.loc[[Interval(3, 6), Interval(3, 6)]] - tm.assert_series_equal(expected, result) + def test_loc_with_overlap(self): idx = IntervalIndex.from_tuples([(1, 5), (3, 7)]) s = Series(range(len(idx)), index=idx) - result = s[4] + # scalar expected = s + result = s.loc[4] tm.assert_series_equal(expected, result) - result = s[[4]] - expected = s + result = s[4] tm.assert_series_equal(expected, result) result = s.loc[[4]] - expected = s tm.assert_series_equal(expected, result) - result = s[Interval(3, 5)] - expected = s + result = s[[4]] + tm.assert_series_equal(expected, result) + + # interval + expected = 0 + result = s.loc[Interval(1, 5)] + tm.assert_series_equal(expected, result) + + result = s[Interval(1, 5)] tm.assert_series_equal(expected, result) - result = s.loc[Interval(3, 5)] expected = s + result = s.loc[[Interval(1, 5), Interval(3, 7)]] + tm.assert_series_equal(expected, result) + + result = s[[Interval(1, 5), Interval(3, 7)]] tm.assert_series_equal(expected, result) - # doesn't intersect unique set of intervals with pytest.raises(KeyError): - s[[Interval(3, 5)]] + s.loc[Interval(3, 5)] with pytest.raises(KeyError): s.loc[[Interval(3, 5)]] - # To be removed, replaced by test_interval_new.py (see #16316, #16386) + with pytest.raises(KeyError): + s[Interval(3, 5)] + + with pytest.raises(KeyError): + s[[Interval(3, 5)]] + + # slices with interval (only exact matches) + expected = s + result = s.loc[Interval(1, 5):Interval(3, 7)] + tm.assert_series_equal(expected, result) + + result = s[Interval(1, 5):Interval(3, 7)] + tm.assert_series_equal(expected, result) + + with pytest.raises(KeyError): + s.loc[Interval(1, 6):Interval(3, 8)] + + with pytest.raises(KeyError): + s[Interval(1, 6):Interval(3, 8)] + + # slices with scalar raise for overlapping intervals + # TODO KeyError is the appropriate error? + with pytest.raises(KeyError): + s.loc[1:4] + def test_non_unique(self): idx = IntervalIndex.from_tuples([(1, 3), (3, 7)]) - s = Series(range(len(idx)), index=idx) result = s.loc[Interval(1, 3)] @@ -195,26 +298,26 @@ def test_non_unique(self): expected = s.iloc[0:1] tm.assert_series_equal(expected, result) - # To be removed, replaced by test_interval_new.py (see #16316, #16386) def test_non_unique_moar(self): idx = IntervalIndex.from_tuples([(1, 3), (1, 3), (3, 7)]) s = Series(range(len(idx)), index=idx) - result = s.loc[Interval(1, 3)] expected = s.iloc[[0, 1]] + result = s.loc[Interval(1, 3)] tm.assert_series_equal(expected, result) - # non-unique index and slices not allowed - with pytest.raises(ValueError): - s.loc[Interval(1, 3):] + expected = s + result = s.loc[Interval(1, 3):] + tm.assert_series_equal(expected, result) - with pytest.raises(ValueError): - s[Interval(1, 3):] + expected = s + result = s[Interval(1, 3):] + tm.assert_series_equal(expected, result) - # non-unique - with pytest.raises(ValueError): - s[[Interval(1, 3)]] + expected = s.iloc[[0, 1]] + result = s[[Interval(1, 3)]] + tm.assert_series_equal(expected, result) # TODO: check this behavior is consistent with test_interval_new.py def test_non_matching(self): diff --git a/pandas/tests/indexing/interval/test_interval_new.py b/pandas/tests/indexing/interval/test_interval_new.py deleted file mode 100644 index 3eb5f38ba0c80..0000000000000 --- a/pandas/tests/indexing/interval/test_interval_new.py +++ /dev/null @@ -1,247 +0,0 @@ -import pytest -import numpy as np - -from pandas import Series, IntervalIndex, Interval -import pandas.util.testing as tm - - -pytestmark = pytest.mark.skip(reason="new indexing tests for issue 16316") - - -class TestIntervalIndex(object): - - def setup_method(self, method): - self.s = Series(np.arange(5), IntervalIndex.from_breaks(np.arange(6))) - - def test_loc_with_interval(self): - - # loc with single label / list of labels: - # - Intervals: only exact matches - # - scalars: those that contain it - - s = self.s - - expected = 0 - result = s.loc[Interval(0, 1)] - assert result == expected - result = s[Interval(0, 1)] - assert result == expected - - expected = s.iloc[3:5] - result = s.loc[[Interval(3, 4), Interval(4, 5)]] - tm.assert_series_equal(expected, result) - result = s[[Interval(3, 4), Interval(4, 5)]] - tm.assert_series_equal(expected, result) - - # missing or not exact - with pytest.raises(KeyError): - s.loc[Interval(3, 5, closed='left')] - - with pytest.raises(KeyError): - s[Interval(3, 5, closed='left')] - - with pytest.raises(KeyError): - s[Interval(3, 5)] - - with pytest.raises(KeyError): - s.loc[Interval(3, 5)] - - with pytest.raises(KeyError): - s[Interval(3, 5)] - - with pytest.raises(KeyError): - s.loc[Interval(-2, 0)] - - with pytest.raises(KeyError): - s[Interval(-2, 0)] - - with pytest.raises(KeyError): - s.loc[Interval(5, 6)] - - with pytest.raises(KeyError): - s[Interval(5, 6)] - - def test_loc_with_scalar(self): - - # loc with single label / list of labels: - # - Intervals: only exact matches - # - scalars: those that contain it - - s = self.s - - assert s.loc[1] == 0 - assert s.loc[1.5] == 1 - assert s.loc[2] == 1 - - # TODO with __getitem__ same rules as loc, or positional ? - # assert s[1] == 0 - # assert s[1.5] == 1 - # assert s[2] == 1 - - expected = s.iloc[1:4] - tm.assert_series_equal(expected, s.loc[[1.5, 2.5, 3.5]]) - tm.assert_series_equal(expected, s.loc[[2, 3, 4]]) - tm.assert_series_equal(expected, s.loc[[1.5, 3, 4]]) - - expected = s.iloc[[1, 1, 2, 1]] - tm.assert_series_equal(expected, s.loc[[1.5, 2, 2.5, 1.5]]) - - expected = s.iloc[2:5] - tm.assert_series_equal(expected, s.loc[s >= 2]) - - def test_loc_with_slices(self): - - # loc with slices: - # - Interval objects: only works with exact matches - # - scalars: only works for non-overlapping, monotonic intervals, - # and start/stop select location based on the interval that - # contains them: - # (slice_loc(start, stop) == (idx.get_loc(start), idx.get_loc(stop)) - - s = self.s - - # slice of interval - - expected = s.iloc[:3] - result = s.loc[Interval(0, 1):Interval(2, 3)] - tm.assert_series_equal(expected, result) - result = s[Interval(0, 1):Interval(2, 3)] - tm.assert_series_equal(expected, result) - - expected = s.iloc[4:] - result = s.loc[Interval(3, 4):] - tm.assert_series_equal(expected, result) - result = s[Interval(3, 4):] - tm.assert_series_equal(expected, result) - - with pytest.raises(KeyError): - s.loc[Interval(3, 6):] - - with pytest.raises(KeyError): - s[Interval(3, 6):] - - with pytest.raises(KeyError): - s.loc[Interval(3, 4, closed='left'):] - - with pytest.raises(KeyError): - s[Interval(3, 4, closed='left'):] - - # TODO with non-existing intervals ? - # s.loc[Interval(-1, 0):Interval(2, 3)] - - # slice of scalar - - expected = s.iloc[:3] - tm.assert_series_equal(expected, s.loc[:3]) - tm.assert_series_equal(expected, s.loc[:2.5]) - tm.assert_series_equal(expected, s.loc[0.1:2.5]) - - # TODO should this work? (-1 is not contained in any of the Intervals) - # tm.assert_series_equal(expected, s.loc[-1:3]) - - # TODO with __getitem__ same rules as loc, or positional ? - # tm.assert_series_equal(expected, s[:3]) - # tm.assert_series_equal(expected, s[:2.5]) - # tm.assert_series_equal(expected, s[0.1:2.5]) - - # slice of scalar with step != 1 - with pytest.raises(NotImplementedError): - s[0:4:2] - - def test_loc_with_overlap(self): - - idx = IntervalIndex.from_tuples([(1, 5), (3, 7)]) - s = Series(range(len(idx)), index=idx) - - # scalar - expected = s - result = s.loc[4] - tm.assert_series_equal(expected, result) - - result = s[4] - tm.assert_series_equal(expected, result) - - result = s.loc[[4]] - tm.assert_series_equal(expected, result) - - result = s[[4]] - tm.assert_series_equal(expected, result) - - # interval - expected = 0 - result = s.loc[Interval(1, 5)] - tm.assert_series_equal(expected, result) - - result = s[Interval(1, 5)] - tm.assert_series_equal(expected, result) - - expected = s - result = s.loc[[Interval(1, 5), Interval(3, 7)]] - tm.assert_series_equal(expected, result) - - result = s[[Interval(1, 5), Interval(3, 7)]] - tm.assert_series_equal(expected, result) - - with pytest.raises(KeyError): - s.loc[Interval(3, 5)] - - with pytest.raises(KeyError): - s.loc[[Interval(3, 5)]] - - with pytest.raises(KeyError): - s[Interval(3, 5)] - - with pytest.raises(KeyError): - s[[Interval(3, 5)]] - - # slices with interval (only exact matches) - expected = s - result = s.loc[Interval(1, 5):Interval(3, 7)] - tm.assert_series_equal(expected, result) - - result = s[Interval(1, 5):Interval(3, 7)] - tm.assert_series_equal(expected, result) - - with pytest.raises(KeyError): - s.loc[Interval(1, 6):Interval(3, 8)] - - with pytest.raises(KeyError): - s[Interval(1, 6):Interval(3, 8)] - - # slices with scalar raise for overlapping intervals - # TODO KeyError is the appropriate error? - with pytest.raises(KeyError): - s.loc[1:4] - - def test_non_unique(self): - - idx = IntervalIndex.from_tuples([(1, 3), (3, 7)]) - s = 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_non_unique_moar(self): - - idx = IntervalIndex.from_tuples([(1, 3), (1, 3), (3, 7)]) - s = Series(range(len(idx)), index=idx) - - expected = s.iloc[[0, 1]] - result = s.loc[Interval(1, 3)] - tm.assert_series_equal(expected, result) - - expected = s - result = s.loc[Interval(1, 3):] - tm.assert_series_equal(expected, result) - - expected = s - result = s[Interval(1, 3):] - tm.assert_series_equal(expected, result) - - expected = s.iloc[[0, 1]] - result = s[[Interval(1, 3)]] - tm.assert_series_equal(expected, result) From d43aa2a957346e8272308c0a2165bcabf075d562 Mon Sep 17 00:00:00 2001 From: Alexander Lenail Date: Mon, 2 Apr 2018 17:28:08 -0400 Subject: [PATCH 2/2] couple more things --- .../tests/indexing/interval/test_interval.py | 21 ++----------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/pandas/tests/indexing/interval/test_interval.py b/pandas/tests/indexing/interval/test_interval.py index f0f91aa75b084..897ed84f77744 100644 --- a/pandas/tests/indexing/interval/test_interval.py +++ b/pandas/tests/indexing/interval/test_interval.py @@ -12,25 +12,6 @@ class TestIntervalIndex(object): def setup_method(self, method): self.s = Series(np.arange(5), IntervalIndex.from_breaks(np.arange(6))) - # To be removed, replaced by test_interval_new.py (see #16316, #16386) - def test_loc_with_scalar(self): - - s = self.s - - expected = s.iloc[:3] - tm.assert_series_equal(expected, s.loc[:3]) - tm.assert_series_equal(expected, s.loc[:2.5]) - tm.assert_series_equal(expected, s.loc[0.1:2.5]) - tm.assert_series_equal(expected, s.loc[-1:3]) - - expected = s.iloc[1:4] - tm.assert_series_equal(expected, s.loc[[1.5, 2.5, 3.5]]) - tm.assert_series_equal(expected, s.loc[[2, 3, 4]]) - tm.assert_series_equal(expected, s.loc[[1.5, 3, 4]]) - - expected = s.iloc[2:5] - tm.assert_series_equal(expected, s.loc[s >= 2]) - # TODO: check this behavior is consistent with test_interval_new.py def test_getitem_with_scalar(self): @@ -50,6 +31,8 @@ def test_getitem_with_scalar(self): expected = s.iloc[2:5] tm.assert_series_equal(expected, s[s >= 2]) + # TODO: where is test_getitem_with_interval? + # TODO: check this behavior is consistent with test_interval_new.py @pytest.mark.parametrize('direction, closed', product(('increasing', 'decreasing'),