From a5871250c1d01e30b52721fb0b043f318794d160 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Wed, 5 Feb 2020 10:41:15 -0800 Subject: [PATCH 1/2] CLN: MultiIndex tests --- pandas/tests/indexes/common.py | 4 ++++ pandas/tests/indexes/multi/conftest.py | 6 ------ pandas/tests/indexes/multi/test_compat.py | 4 ++-- pandas/tests/indexes/multi/test_sorting.py | 4 ++-- pandas/tests/indexes/multi/test_take.py | 0 5 files changed, 8 insertions(+), 10 deletions(-) create mode 100644 pandas/tests/indexes/multi/test_take.py diff --git a/pandas/tests/indexes/common.py b/pandas/tests/indexes/common.py index 26d120619defc..da27057a783ab 100644 --- a/pandas/tests/indexes/common.py +++ b/pandas/tests/indexes/common.py @@ -167,6 +167,10 @@ def test_create_index_existing_name(self): def test_numeric_compat(self): idx = self.create_index() + # Check that this doesn't cover MultiIndex case, if/when it does, + # we can remove multi.test_compat.test_numeric_compat + assert not isinstance(idx, MultiIndex) + with pytest.raises(TypeError, match="cannot perform __mul__"): idx * 1 with pytest.raises(TypeError, match="cannot perform __rmul__"): diff --git a/pandas/tests/indexes/multi/conftest.py b/pandas/tests/indexes/multi/conftest.py index acaea4ff96ff5..67ebfcddf6c2d 100644 --- a/pandas/tests/indexes/multi/conftest.py +++ b/pandas/tests/indexes/multi/conftest.py @@ -49,12 +49,6 @@ def index_names(): return ["first", "second"] -@pytest.fixture -def holder(): - # the MultiIndex constructor used to base compatibility with pickle - return MultiIndex - - @pytest.fixture def compat_props(): # a MultiIndex must have these properties associated with it diff --git a/pandas/tests/indexes/multi/test_compat.py b/pandas/tests/indexes/multi/test_compat.py index 545a7ddef29bb..9a76f0623eb31 100644 --- a/pandas/tests/indexes/multi/test_compat.py +++ b/pandas/tests/indexes/multi/test_compat.py @@ -112,8 +112,8 @@ def test_ndarray_compat_properties(idx, compat_props): idx.values.nbytes -def test_pickle_compat_construction(holder): +def test_pickle_compat_construction(): # this is testing for pickle compat # need an object to create with with pytest.raises(TypeError, match="Must pass both levels and codes"): - holder() + MultiIndex() diff --git a/pandas/tests/indexes/multi/test_sorting.py b/pandas/tests/indexes/multi/test_sorting.py index 50242c1cac549..bb40612b9a55a 100644 --- a/pandas/tests/indexes/multi/test_sorting.py +++ b/pandas/tests/indexes/multi/test_sorting.py @@ -1,3 +1,5 @@ +import random + import numpy as np import pytest @@ -9,8 +11,6 @@ def test_sortlevel(idx): - import random - tuples = list(idx) random.shuffle(tuples) diff --git a/pandas/tests/indexes/multi/test_take.py b/pandas/tests/indexes/multi/test_take.py new file mode 100644 index 0000000000000..e69de29bb2d1d From 94329ed339d4f2e14874f75d288417096df64a77 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Wed, 5 Feb 2020 10:43:09 -0800 Subject: [PATCH 2/2] implement test_take --- pandas/tests/indexes/multi/test_analytics.py | 77 ------------------ pandas/tests/indexes/multi/test_take.py | 82 ++++++++++++++++++++ 2 files changed, 82 insertions(+), 77 deletions(-) diff --git a/pandas/tests/indexes/multi/test_analytics.py b/pandas/tests/indexes/multi/test_analytics.py index e64511efd7ffb..a9e02934f27ab 100644 --- a/pandas/tests/indexes/multi/test_analytics.py +++ b/pandas/tests/indexes/multi/test_analytics.py @@ -146,83 +146,6 @@ def test_append_mixed_dtypes(): tm.assert_index_equal(res, exp) -def test_take(idx): - indexer = [4, 3, 0, 2] - result = idx.take(indexer) - expected = idx[indexer] - assert result.equals(expected) - - # TODO: Remove Commented Code - # if not isinstance(idx, - # (DatetimeIndex, PeriodIndex, TimedeltaIndex)): - # GH 10791 - msg = "'MultiIndex' object has no attribute 'freq'" - with pytest.raises(AttributeError, match=msg): - idx.freq - - -def test_take_invalid_kwargs(idx): - idx = idx - indices = [1, 2] - - msg = r"take\(\) got an unexpected keyword argument 'foo'" - with pytest.raises(TypeError, match=msg): - idx.take(indices, foo=2) - - msg = "the 'out' parameter is not supported" - with pytest.raises(ValueError, match=msg): - idx.take(indices, out=indices) - - msg = "the 'mode' parameter is not supported" - with pytest.raises(ValueError, match=msg): - idx.take(indices, mode="clip") - - -def test_take_fill_value(): - # GH 12631 - vals = [["A", "B"], [pd.Timestamp("2011-01-01"), pd.Timestamp("2011-01-02")]] - idx = pd.MultiIndex.from_product(vals, names=["str", "dt"]) - - result = idx.take(np.array([1, 0, -1])) - exp_vals = [ - ("A", pd.Timestamp("2011-01-02")), - ("A", pd.Timestamp("2011-01-01")), - ("B", pd.Timestamp("2011-01-02")), - ] - expected = pd.MultiIndex.from_tuples(exp_vals, names=["str", "dt"]) - tm.assert_index_equal(result, expected) - - # fill_value - result = idx.take(np.array([1, 0, -1]), fill_value=True) - exp_vals = [ - ("A", pd.Timestamp("2011-01-02")), - ("A", pd.Timestamp("2011-01-01")), - (np.nan, pd.NaT), - ] - expected = pd.MultiIndex.from_tuples(exp_vals, names=["str", "dt"]) - tm.assert_index_equal(result, expected) - - # allow_fill=False - result = idx.take(np.array([1, 0, -1]), allow_fill=False, fill_value=True) - exp_vals = [ - ("A", pd.Timestamp("2011-01-02")), - ("A", pd.Timestamp("2011-01-01")), - ("B", pd.Timestamp("2011-01-02")), - ] - expected = pd.MultiIndex.from_tuples(exp_vals, names=["str", "dt"]) - tm.assert_index_equal(result, expected) - - msg = "When allow_fill=True and fill_value is not None, all indices must be >= -1" - with pytest.raises(ValueError, match=msg): - idx.take(np.array([1, 0, -2]), fill_value=True) - with pytest.raises(ValueError, match=msg): - idx.take(np.array([1, 0, -5]), fill_value=True) - - msg = "index -5 is out of bounds for( axis 0 with)? size 4" - with pytest.raises(IndexError, match=msg): - idx.take(np.array([1, -5])) - - def test_iter(idx): result = list(idx) expected = [ diff --git a/pandas/tests/indexes/multi/test_take.py b/pandas/tests/indexes/multi/test_take.py index e69de29bb2d1d..85043ff8812af 100644 --- a/pandas/tests/indexes/multi/test_take.py +++ b/pandas/tests/indexes/multi/test_take.py @@ -0,0 +1,82 @@ +import numpy as np +import pytest + +import pandas as pd +import pandas._testing as tm + + +def test_take(idx): + indexer = [4, 3, 0, 2] + result = idx.take(indexer) + expected = idx[indexer] + assert result.equals(expected) + + # FIXME: Remove Commented Code + # if not isinstance(idx, + # (DatetimeIndex, PeriodIndex, TimedeltaIndex)): + # GH 10791 + msg = "'MultiIndex' object has no attribute 'freq'" + with pytest.raises(AttributeError, match=msg): + idx.freq + + +def test_take_invalid_kwargs(idx): + idx = idx + indices = [1, 2] + + msg = r"take\(\) got an unexpected keyword argument 'foo'" + with pytest.raises(TypeError, match=msg): + idx.take(indices, foo=2) + + msg = "the 'out' parameter is not supported" + with pytest.raises(ValueError, match=msg): + idx.take(indices, out=indices) + + msg = "the 'mode' parameter is not supported" + with pytest.raises(ValueError, match=msg): + idx.take(indices, mode="clip") + + +def test_take_fill_value(): + # GH 12631 + vals = [["A", "B"], [pd.Timestamp("2011-01-01"), pd.Timestamp("2011-01-02")]] + idx = pd.MultiIndex.from_product(vals, names=["str", "dt"]) + + result = idx.take(np.array([1, 0, -1])) + exp_vals = [ + ("A", pd.Timestamp("2011-01-02")), + ("A", pd.Timestamp("2011-01-01")), + ("B", pd.Timestamp("2011-01-02")), + ] + expected = pd.MultiIndex.from_tuples(exp_vals, names=["str", "dt"]) + tm.assert_index_equal(result, expected) + + # fill_value + result = idx.take(np.array([1, 0, -1]), fill_value=True) + exp_vals = [ + ("A", pd.Timestamp("2011-01-02")), + ("A", pd.Timestamp("2011-01-01")), + (np.nan, pd.NaT), + ] + expected = pd.MultiIndex.from_tuples(exp_vals, names=["str", "dt"]) + tm.assert_index_equal(result, expected) + + # allow_fill=False + result = idx.take(np.array([1, 0, -1]), allow_fill=False, fill_value=True) + exp_vals = [ + ("A", pd.Timestamp("2011-01-02")), + ("A", pd.Timestamp("2011-01-01")), + ("B", pd.Timestamp("2011-01-02")), + ] + expected = pd.MultiIndex.from_tuples(exp_vals, names=["str", "dt"]) + tm.assert_index_equal(result, expected) + + msg = "When allow_fill=True and fill_value is not None, all indices must be >= -1" + with pytest.raises(ValueError, match=msg): + idx.take(np.array([1, 0, -2]), fill_value=True) + with pytest.raises(ValueError, match=msg): + idx.take(np.array([1, 0, -5]), fill_value=True) + + msg = "index -5 is out of bounds for( axis 0 with)? size 4" + with pytest.raises(IndexError, match=msg): + idx.take(np.array([1, -5]))