From 3d93ec0492b22913f140e93ea96f63e39b525c25 Mon Sep 17 00:00:00 2001 From: Martin Winkel Date: Fri, 6 Mar 2020 10:40:55 +0100 Subject: [PATCH 1/6] removed redundant index test from tests/base/test_ops.py --- pandas/tests/base/test_ops.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/pandas/tests/base/test_ops.py b/pandas/tests/base/test_ops.py index 8f48d0a3e8378..ba46876ff4f4b 100644 --- a/pandas/tests/base/test_ops.py +++ b/pandas/tests/base/test_ops.py @@ -851,23 +851,6 @@ def test_access_by_position(self, indices): with pytest.raises(IndexError, match=msg): series.iloc[size] - @pytest.mark.parametrize("indexer_klass", [list, pd.Index]) - @pytest.mark.parametrize( - "indexer", - [ - [True] * 10, - [False] * 10, - [True, False, True, True, False, False, True, True, False, True], - ], - ) - def test_bool_indexing(self, indexer_klass, indexer): - # GH 22533 - for idx in self.indexes: - exp_idx = [i for i in range(len(indexer)) if indexer[i]] - tm.assert_index_equal(idx[indexer_klass(indexer)], idx[exp_idx]) - s = pd.Series(idx) - tm.assert_series_equal(s[indexer_klass(indexer)], s.iloc[exp_idx]) - def test_get_indexer_non_unique_dtype_mismatch(self): # GH 25459 indexes, missing = pd.Index(["A", "B"]).get_indexer_non_unique(pd.Index([0])) From 21621588e43c74b279af5cba5992a86a8565a158 Mon Sep 17 00:00:00 2001 From: Martin Winkel Date: Sun, 8 Mar 2020 19:27:53 +0100 Subject: [PATCH 2/6] refactored and split test_series_mask_boolean --- pandas/tests/indexing/test_na_indexing.py | 67 ++++++++++++++++++----- 1 file changed, 54 insertions(+), 13 deletions(-) diff --git a/pandas/tests/indexing/test_na_indexing.py b/pandas/tests/indexing/test_na_indexing.py index 345ca30ec77eb..82014e25af664 100644 --- a/pandas/tests/indexing/test_na_indexing.py +++ b/pandas/tests/indexing/test_na_indexing.py @@ -22,38 +22,79 @@ @pytest.mark.parametrize( "mask", [[True, False, False], [True, True, True], [False, False, False]] ) -@pytest.mark.parametrize("box_mask", [True, False]) +@pytest.mark.parametrize("indexer_class", [list, pd.array, pd.Index, pd.Series]) @pytest.mark.parametrize("frame", [True, False]) -def test_series_mask_boolean(values, dtype, mask, box_mask, frame): +def test_series_mask_boolean(values, dtype, mask, indexer_class, frame): ser = pd.Series(values, dtype=dtype, index=["a", "b", "c"]) if frame: ser = ser.to_frame() - mask = pd.array(mask, dtype="boolean") - if box_mask: + + if indexer_class is pd.array: + mask = pd.array(mask, dtype="boolean") + elif indexer_class is pd.Series: mask = pd.Series(mask, index=ser.index) + else: + mask = indexer_class(mask) - expected = ser[mask.astype("bool")] + expected = ser[mask] result = ser[mask] tm.assert_equal(result, expected) - if not box_mask: - # Series.iloc[Series[bool]] isn't allowed + msg = "iLocation based boolean indexing cannot use an indexable as a mask" + if indexer_class is pd.Series: + with pytest.raises((ValueError, TypeError), match=msg): + result = ser.iloc[mask] + tm.assert_equal(result, expected) + else: result = ser.iloc[mask] tm.assert_equal(result, expected) result = ser.loc[mask] tm.assert_equal(result, expected) - # empty - mask = mask[:0] - ser = ser.iloc[:0] - expected = ser[mask.astype("bool")] + +@pytest.mark.parametrize( + "dtype", + [ + "int64", + "float64", + "object", + "string", + "datetime64[ns]", + "datetime64[ns, CET]", + "timedelta64[ns]", + "Period[D]", + "Sparse", + "interval", + ], +) +@pytest.mark.parametrize("indexer_class", [list, pd.array, pd.Index, pd.Series]) +@pytest.mark.parametrize("frame", [True, False]) +def test_series_mask_boolean_empty(dtype, indexer_class, frame): + if frame: + ser = pd.DataFrame(dtype=dtype) + else: + ser = pd.Series(dtype=dtype) + + mask = [] + if indexer_class is pd.array: + mask = pd.array(mask, dtype="boolean") + elif indexer_class is pd.Series: + mask = pd.Series(mask, index=ser.index, dtype="boolean") + else: + mask = indexer_class(mask) + + expected = ser[mask] result = ser[mask] tm.assert_equal(result, expected) - if not box_mask: - # Series.iloc[Series[bool]] isn't allowed + msg = "iLocation based boolean indexing cannot use an indexable as a mask" + if indexer_class is pd.Series: + with pytest.raises((ValueError, TypeError), match=msg): + result = ser.iloc[mask] + tm.assert_equal(result, expected) + else: result = ser.iloc[mask] tm.assert_equal(result, expected) From c724ba0c600d58ec4baa0a59f4103b882493627d Mon Sep 17 00:00:00 2001 From: Martin Winkel Date: Sun, 8 Mar 2020 19:30:18 +0100 Subject: [PATCH 3/6] tightened the pytest.raises condition --- pandas/tests/indexing/test_na_indexing.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/tests/indexing/test_na_indexing.py b/pandas/tests/indexing/test_na_indexing.py index 82014e25af664..cb48f303d3e83 100644 --- a/pandas/tests/indexing/test_na_indexing.py +++ b/pandas/tests/indexing/test_na_indexing.py @@ -43,7 +43,7 @@ def test_series_mask_boolean(values, dtype, mask, indexer_class, frame): msg = "iLocation based boolean indexing cannot use an indexable as a mask" if indexer_class is pd.Series: - with pytest.raises((ValueError, TypeError), match=msg): + with pytest.raises(ValueError, match=msg): result = ser.iloc[mask] tm.assert_equal(result, expected) else: @@ -91,7 +91,7 @@ def test_series_mask_boolean_empty(dtype, indexer_class, frame): msg = "iLocation based boolean indexing cannot use an indexable as a mask" if indexer_class is pd.Series: - with pytest.raises((ValueError, TypeError), match=msg): + with pytest.raises(ValueError, match=msg): result = ser.iloc[mask] tm.assert_equal(result, expected) else: From 46cc8835adbbfef1d3eec611f8e865bcfcb9ff16 Mon Sep 17 00:00:00 2001 From: Martin Winkel Date: Sun, 8 Mar 2020 20:18:07 +0100 Subject: [PATCH 4/6] renaming and added a comment --- pandas/tests/indexing/test_na_indexing.py | 75 ++++++----------------- 1 file changed, 18 insertions(+), 57 deletions(-) diff --git a/pandas/tests/indexing/test_na_indexing.py b/pandas/tests/indexing/test_na_indexing.py index cb48f303d3e83..9e8ef6e6e1c22 100644 --- a/pandas/tests/indexing/test_na_indexing.py +++ b/pandas/tests/indexing/test_na_indexing.py @@ -7,6 +7,7 @@ @pytest.mark.parametrize( "values, dtype", [ + ([], "object"), ([1, 2, 3], "int64"), ([1.0, 2.0, 3.0], "float64"), (["a", "b", "c"], "object"), @@ -25,80 +26,40 @@ @pytest.mark.parametrize("indexer_class", [list, pd.array, pd.Index, pd.Series]) @pytest.mark.parametrize("frame", [True, False]) def test_series_mask_boolean(values, dtype, mask, indexer_class, frame): - ser = pd.Series(values, dtype=dtype, index=["a", "b", "c"]) - if frame: - ser = ser.to_frame() - - if indexer_class is pd.array: - mask = pd.array(mask, dtype="boolean") - elif indexer_class is pd.Series: - mask = pd.Series(mask, index=ser.index) - else: - mask = indexer_class(mask) + # In case len(values) < 3 + index = ["a", "b", "c"][: len(values)] + mask = mask[: len(values)] - expected = ser[mask] - - result = ser[mask] - tm.assert_equal(result, expected) - - msg = "iLocation based boolean indexing cannot use an indexable as a mask" - if indexer_class is pd.Series: - with pytest.raises(ValueError, match=msg): - result = ser.iloc[mask] - tm.assert_equal(result, expected) - else: - result = ser.iloc[mask] - tm.assert_equal(result, expected) - - result = ser.loc[mask] - tm.assert_equal(result, expected) - - -@pytest.mark.parametrize( - "dtype", - [ - "int64", - "float64", - "object", - "string", - "datetime64[ns]", - "datetime64[ns, CET]", - "timedelta64[ns]", - "Period[D]", - "Sparse", - "interval", - ], -) -@pytest.mark.parametrize("indexer_class", [list, pd.array, pd.Index, pd.Series]) -@pytest.mark.parametrize("frame", [True, False]) -def test_series_mask_boolean_empty(dtype, indexer_class, frame): + obj = pd.Series(values, dtype=dtype, index=index) if frame: - ser = pd.DataFrame(dtype=dtype) - else: - ser = pd.Series(dtype=dtype) + if len(values) == 0: + # Otherwise obj is an empty DataFrame with shape (0, 1) + obj = pd.DataFrame(dtype=dtype) + else: + obj = obj.to_frame() - mask = [] if indexer_class is pd.array: mask = pd.array(mask, dtype="boolean") elif indexer_class is pd.Series: - mask = pd.Series(mask, index=ser.index, dtype="boolean") + mask = pd.Series(mask, index=obj.index, dtype="boolean") else: mask = indexer_class(mask) - expected = ser[mask] - result = ser[mask] + expected = obj[mask] + + result = obj[mask] tm.assert_equal(result, expected) - msg = "iLocation based boolean indexing cannot use an indexable as a mask" if indexer_class is pd.Series: + msg = "iLocation based boolean indexing cannot use an indexable as a mask" with pytest.raises(ValueError, match=msg): - result = ser.iloc[mask] + result = obj.iloc[mask] tm.assert_equal(result, expected) else: - result = ser.iloc[mask] + result = obj.iloc[mask] tm.assert_equal(result, expected) - result = ser.loc[mask] + result = obj.loc[mask] tm.assert_equal(result, expected) From 3b4c786c12a99caec7225df313e85a05b0fd9d1c Mon Sep 17 00:00:00 2001 From: Martin Winkel Date: Sun, 8 Mar 2020 20:31:25 +0100 Subject: [PATCH 5/6] removed some redundancy in the test case --- pandas/tests/indexing/test_na_indexing.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pandas/tests/indexing/test_na_indexing.py b/pandas/tests/indexing/test_na_indexing.py index 9e8ef6e6e1c22..c5ace07bc83f2 100644 --- a/pandas/tests/indexing/test_na_indexing.py +++ b/pandas/tests/indexing/test_na_indexing.py @@ -1,3 +1,5 @@ +from contextlib import nullcontext as do_not_raise + import pytest import pandas as pd @@ -52,10 +54,11 @@ def test_series_mask_boolean(values, dtype, mask, indexer_class, frame): if indexer_class is pd.Series: msg = "iLocation based boolean indexing cannot use an indexable as a mask" - with pytest.raises(ValueError, match=msg): - result = obj.iloc[mask] - tm.assert_equal(result, expected) + expectation = pytest.raises(ValueError, match=msg) else: + expectation = do_not_raise() + + with expectation: result = obj.iloc[mask] tm.assert_equal(result, expected) From 14ea372cf7df78957088232c931c7c86864b9d07 Mon Sep 17 00:00:00 2001 From: Martin Winkel Date: Sun, 8 Mar 2020 22:36:34 +0100 Subject: [PATCH 6/6] Revert "removed some redundancy in the test case" This reverts commit 3b4c786c12a99caec7225df313e85a05b0fd9d1c. --- pandas/tests/indexing/test_na_indexing.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/pandas/tests/indexing/test_na_indexing.py b/pandas/tests/indexing/test_na_indexing.py index c5ace07bc83f2..9e8ef6e6e1c22 100644 --- a/pandas/tests/indexing/test_na_indexing.py +++ b/pandas/tests/indexing/test_na_indexing.py @@ -1,5 +1,3 @@ -from contextlib import nullcontext as do_not_raise - import pytest import pandas as pd @@ -54,11 +52,10 @@ def test_series_mask_boolean(values, dtype, mask, indexer_class, frame): if indexer_class is pd.Series: msg = "iLocation based boolean indexing cannot use an indexable as a mask" - expectation = pytest.raises(ValueError, match=msg) + with pytest.raises(ValueError, match=msg): + result = obj.iloc[mask] + tm.assert_equal(result, expected) else: - expectation = do_not_raise() - - with expectation: result = obj.iloc[mask] tm.assert_equal(result, expected)