From 6239b321607cf154f9cb2ba1268a9ae9f8c08ad3 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Wed, 29 Apr 2020 08:45:54 -0700 Subject: [PATCH 1/3] parametrize/de-duplicate tests --- .../indexes/datetimes/test_partial_slicing.py | 77 ++++++++----------- .../indexes/multi/test_partial_indexing.py | 61 ++++++++------- .../indexes/period/test_partial_slicing.py | 24 ++---- .../timedeltas/test_partial_slicing.py | 14 +--- pandas/tests/series/indexing/test_indexing.py | 31 +++++++- 5 files changed, 103 insertions(+), 104 deletions(-) diff --git a/pandas/tests/indexes/datetimes/test_partial_slicing.py b/pandas/tests/indexes/datetimes/test_partial_slicing.py index 028a713a8af81..32533263edd3c 100644 --- a/pandas/tests/indexes/datetimes/test_partial_slicing.py +++ b/pandas/tests/indexes/datetimes/test_partial_slicing.py @@ -6,11 +6,11 @@ import numpy as np import pytest -import pandas as pd from pandas import ( DataFrame, DatetimeIndex, Index, + IndexSlice, Series, Timedelta, Timestamp, @@ -23,7 +23,7 @@ class TestSlicing: def test_slice_with_negative_step(self): ts = Series(np.arange(20), date_range("2014-01-01", periods=20, freq="MS")) - SLC = pd.IndexSlice + SLC = IndexSlice def assert_slices_equivalent(l_slc, i_slc): expected = ts.iloc[i_slc] @@ -51,21 +51,12 @@ def assert_slices_equivalent(l_slc, i_slc): assert_slices_equivalent(SLC["2014-10-01":"2015-02-01":-1], SLC[0:0:-1]) - def test_slice_with_zero_step_raises(self): - ts = Series(np.arange(20), date_range("2014-01-01", periods=20, freq="MS")) - with pytest.raises(ValueError, match="slice step cannot be zero"): - ts[::0] - with pytest.raises(ValueError, match="slice step cannot be zero"): - ts.loc[::0] - with pytest.raises(ValueError, match="slice step cannot be zero"): - ts.loc[::0] - def test_monotone_DTI_indexing_bug(self): # GH 19362 # Testing accessing the first element in a monotonic descending # partial string indexing. - df = pd.DataFrame(list(range(5))) + df = DataFrame(list(range(5))) date_list = [ "2018-01-02", "2017-02-10", @@ -73,17 +64,13 @@ def test_monotone_DTI_indexing_bug(self): "2015-03-15", "2014-03-16", ] - date_index = pd.to_datetime(date_list) + date_index = DatetimeIndex(date_list) df["date"] = date_index - expected = pd.DataFrame({0: list(range(5)), "date": date_index}) + expected = DataFrame({0: list(range(5)), "date": date_index}) tm.assert_frame_equal(df, expected) - df = pd.DataFrame( - {"A": [1, 2, 3]}, index=pd.date_range("20170101", periods=3)[::-1] - ) - expected = pd.DataFrame( - {"A": 1}, index=pd.date_range("20170103", periods=1)[::-1] - ) + df = DataFrame({"A": [1, 2, 3]}, index=date_range("20170101", periods=3)[::-1]) + expected = DataFrame({"A": 1}, index=date_range("20170103", periods=1)[::-1]) tm.assert_frame_equal(df.loc["2017-01-03"], expected) def test_slice_year(self): @@ -120,7 +107,7 @@ def test_slice_end_of_period_resolution(self, partial_dtime): # GH#31064 dti = date_range("2019-12-31 23:59:55.999999999", periods=10, freq="s") - ser = pd.Series(range(10), index=dti) + ser = Series(range(10), index=dti) result = ser[partial_dtime] expected = ser.iloc[:5] tm.assert_series_equal(result, expected) @@ -321,7 +308,7 @@ def test_partial_slicing_with_multiindex(self): tm.assert_frame_equal(result, expected) expected = df_multi.loc[ - (pd.Timestamp("2013-06-19 09:30:00", tz=None), "ACCT1", "ABC") + (Timestamp("2013-06-19 09:30:00", tz=None), "ACCT1", "ABC") ] result = df_multi.loc[("2013-06-19 09:30:00", "ACCT1", "ABC")] tm.assert_series_equal(result, expected) @@ -334,31 +321,31 @@ def test_partial_slicing_with_multiindex(self): # GH 4294 # partial slice on a series mi - s = pd.DataFrame( - np.random.rand(1000, 1000), index=pd.date_range("2000-1-1", periods=1000) + s = DataFrame( + np.random.rand(1000, 1000), index=date_range("2000-1-1", periods=1000) ).stack() s2 = s[:-1].copy() expected = s2["2000-1-4"] - result = s2[pd.Timestamp("2000-1-4")] + result = s2[Timestamp("2000-1-4")] tm.assert_series_equal(result, expected) - result = s[pd.Timestamp("2000-1-4")] + result = s[Timestamp("2000-1-4")] expected = s["2000-1-4"] tm.assert_series_equal(result, expected) - df2 = pd.DataFrame(s) + df2 = DataFrame(s) expected = df2.xs("2000-1-4") - result = df2.loc[pd.Timestamp("2000-1-4")] + result = df2.loc[Timestamp("2000-1-4")] tm.assert_frame_equal(result, expected) def test_partial_slice_doesnt_require_monotonicity(self): # For historical reasons. - s = pd.Series(np.arange(10), pd.date_range("2014-01-01", periods=10)) + s = Series(np.arange(10), date_range("2014-01-01", periods=10)) nonmonotonic = s[[3, 5, 4]] expected = nonmonotonic.iloc[:0] - timestamp = pd.Timestamp("2014-01-10") + timestamp = Timestamp("2014-01-10") tm.assert_series_equal(nonmonotonic["2014-01-10":], expected) with pytest.raises(KeyError, match=r"Timestamp\('2014-01-10 00:00:00'\)"): @@ -370,9 +357,9 @@ def test_partial_slice_doesnt_require_monotonicity(self): def test_loc_datetime_length_one(self): # GH16071 - df = pd.DataFrame( + df = DataFrame( columns=["1"], - index=pd.date_range("2016-10-01T00:00:00", "2016-10-01T23:59:59"), + index=date_range("2016-10-01T00:00:00", "2016-10-01T23:59:59"), ) result = df.loc[datetime(2016, 10, 1) :] tm.assert_frame_equal(result, df) @@ -403,10 +390,10 @@ def test_selection_by_datetimelike(self, datetimelike, op, expected): df = DataFrame( { "A": [ - pd.Timestamp("20120101"), - pd.Timestamp("20130101"), + Timestamp("20120101"), + Timestamp("20130101"), np.nan, - pd.Timestamp("20130103"), + Timestamp("20130103"), ] } ) @@ -418,26 +405,26 @@ def test_selection_by_datetimelike(self, datetimelike, op, expected): "start", [ "2018-12-02 21:50:00+00:00", - pd.Timestamp("2018-12-02 21:50:00+00:00"), - pd.Timestamp("2018-12-02 21:50:00+00:00").to_pydatetime(), + Timestamp("2018-12-02 21:50:00+00:00"), + Timestamp("2018-12-02 21:50:00+00:00").to_pydatetime(), ], ) @pytest.mark.parametrize( "end", [ "2018-12-02 21:52:00+00:00", - pd.Timestamp("2018-12-02 21:52:00+00:00"), - pd.Timestamp("2018-12-02 21:52:00+00:00").to_pydatetime(), + Timestamp("2018-12-02 21:52:00+00:00"), + Timestamp("2018-12-02 21:52:00+00:00").to_pydatetime(), ], ) def test_getitem_with_datestring_with_UTC_offset(self, start, end): # GH 24076 - idx = pd.date_range( + idx = date_range( start="2018-12-02 14:50:00-07:00", end="2018-12-02 14:50:00-07:00", freq="1min", ) - df = pd.DataFrame(1, index=idx, columns=["A"]) + df = DataFrame(1, index=idx, columns=["A"]) result = df[start:end] expected = df.iloc[0:3, :] tm.assert_frame_equal(result, expected) @@ -454,11 +441,9 @@ def test_getitem_with_datestring_with_UTC_offset(self, start, end): def test_slice_reduce_to_series(self): # GH 27516 - df = pd.DataFrame( - {"A": range(24)}, index=pd.date_range("2000", periods=24, freq="M") - ) - expected = pd.Series( - range(12), index=pd.date_range("2000", periods=12, freq="M"), name="A" + df = DataFrame({"A": range(24)}, index=date_range("2000", periods=24, freq="M")) + expected = Series( + range(12), index=date_range("2000", periods=12, freq="M"), name="A" ) result = df.loc["2000", "A"] tm.assert_series_equal(result, expected) diff --git a/pandas/tests/indexes/multi/test_partial_indexing.py b/pandas/tests/indexes/multi/test_partial_indexing.py index b00018d2ceb69..7dfe0b20a7478 100644 --- a/pandas/tests/indexes/multi/test_partial_indexing.py +++ b/pandas/tests/indexes/multi/test_partial_indexing.py @@ -1,19 +1,11 @@ -import numpy as np import pytest -import pandas as pd -from pandas import DataFrame, MultiIndex, date_range +from pandas import DataFrame, IndexSlice, MultiIndex, date_range import pandas._testing as tm -def test_partial_string_timestamp_multiindex(): - # GH10331 - dr = pd.date_range("2016-01-01", "2016-01-03", freq="12H") - abc = ["a", "b", "c"] - ix = pd.MultiIndex.from_product([dr, abc]) - df = pd.DataFrame({"c1": range(0, 15)}, index=ix) - idx = pd.IndexSlice - +@pytest.fixture +def df(): # c1 # 2016-01-01 00:00:00 a 0 # b 1 @@ -30,33 +22,39 @@ def test_partial_string_timestamp_multiindex(): # 2016-01-03 00:00:00 a 12 # b 13 # c 14 + dr = date_range("2016-01-01", "2016-01-03", freq="12H") + abc = ["a", "b", "c"] + mi = MultiIndex.from_product([dr, abc]) + frame = DataFrame({"c1": range(0, 15)}, index=mi) + return frame + +def test_partial_string_matching_single_index(df): # partial string matching on a single index - for df_swap in (df.swaplevel(), df.swaplevel(0), df.swaplevel(0, 1)): + for df_swap in [df.swaplevel(), df.swaplevel(0), df.swaplevel(0, 1)]: df_swap = df_swap.sort_index() just_a = df_swap.loc["a"] result = just_a.loc["2016-01-01"] - expected = df.loc[idx[:, "a"], :].iloc[0:2] + expected = df.loc[IndexSlice[:, "a"], :].iloc[0:2] expected.index = expected.index.droplevel(1) tm.assert_frame_equal(result, expected) + +def test_partial_string_timestamp_multiindex(df): + # GH10331 + df_swap = df.swaplevel(0, 1).sort_index() + SLC = IndexSlice + # indexing with IndexSlice - result = df.loc[idx["2016-01-01":"2016-02-01", :], :] + result = df.loc[SLC["2016-01-01":"2016-02-01", :], :] expected = df tm.assert_frame_equal(result, expected) # match on secondary index - result = df_swap.loc[idx[:, "2016-01-01":"2016-01-01"], :] + result = df_swap.loc[SLC[:, "2016-01-01":"2016-01-01"], :] expected = df_swap.iloc[[0, 1, 5, 6, 10, 11]] tm.assert_frame_equal(result, expected) - # Even though this syntax works on a single index, this is somewhat - # ambiguous and we don't want to extend this behavior forward to work - # in multi-indexes. This would amount to selecting a scalar from a - # column. - with pytest.raises(KeyError, match="'2016-01-01'"): - df["2016-01-01"] - # partial string match on year only result = df.loc["2016"] expected = df @@ -73,7 +71,7 @@ def test_partial_string_timestamp_multiindex(): tm.assert_frame_equal(result, expected) # partial string match on secondary index - result = df_swap.loc[idx[:, "2016-01-02"], :] + result = df_swap.loc[SLC[:, "2016-01-02"], :] expected = df_swap.iloc[[2, 3, 7, 8, 12, 13]] tm.assert_frame_equal(result, expected) @@ -86,11 +84,18 @@ def test_partial_string_timestamp_multiindex(): with pytest.raises(KeyError, match="'2016-01-01'"): df_swap.loc["2016-01-01"] - # GH12685 (partial string with daily resolution or below) - dr = date_range("2013-01-01", periods=100, freq="D") - ix = MultiIndex.from_product([dr, ["a", "b"]]) - df = DataFrame(np.random.randn(200, 1), columns=["A"], index=ix) - result = df.loc[idx["2013-03":"2013-03", :], :] +def test_partial_string_timestamp_multiindex_str_key_raises(df): + # Even though this syntax works on a single index, this is somewhat + # ambiguous and we don't want to extend this behavior forward to work + # in multi-indexes. This would amount to selecting a scalar from a + # column. + with pytest.raises(KeyError, match="'2016-01-01'"): + df["2016-01-01"] + + +def test_partial_string_timestamp_multiindex_daily_resolution(df): + # GH12685 (partial string with daily resolution or below) + result = df.loc[IndexSlice["2013-03":"2013-03", :], :] expected = df.iloc[118:180] tm.assert_frame_equal(result, expected) diff --git a/pandas/tests/indexes/period/test_partial_slicing.py b/pandas/tests/indexes/period/test_partial_slicing.py index ad9ee7bd2594d..d2d2b38dcf1d2 100644 --- a/pandas/tests/indexes/period/test_partial_slicing.py +++ b/pandas/tests/indexes/period/test_partial_slicing.py @@ -1,15 +1,14 @@ import numpy as np import pytest -import pandas as pd -from pandas import DataFrame, Period, Series, period_range +from pandas import DataFrame, IndexSlice, Period, Series, date_range, period_range import pandas._testing as tm class TestPeriodIndex: def test_slice_with_negative_step(self): ts = Series(np.arange(20), period_range("2014-01", periods=20, freq="M")) - SLC = pd.IndexSlice + SLC = IndexSlice def assert_slices_equivalent(l_slc, i_slc): tm.assert_series_equal(ts[l_slc], ts.iloc[i_slc]) @@ -31,15 +30,6 @@ def assert_slices_equivalent(l_slc, i_slc): assert_slices_equivalent(SLC["2014-10":"2015-02":-1], SLC[:0]) - def test_slice_with_zero_step_raises(self): - ts = Series(np.arange(20), period_range("2014-01", periods=20, freq="M")) - with pytest.raises(ValueError, match="slice step cannot be zero"): - ts[::0] - with pytest.raises(ValueError, match="slice step cannot be zero"): - ts.loc[::0] - with pytest.raises(ValueError, match="slice step cannot be zero"): - ts.loc[::0] - def test_pindex_slice_index(self): pi = period_range(start="1/1/10", end="12/31/12", freq="M") s = Series(np.random.rand(len(pi)), index=pi) @@ -52,7 +42,7 @@ def test_pindex_slice_index(self): def test_range_slice_day(self): # GH#6716 - didx = pd.date_range(start="2013/01/01", freq="D", periods=400) + didx = date_range(start="2013/01/01", freq="D", periods=400) pidx = period_range(start="2013/01/01", freq="D", periods=400) msg = "slice indices must be integers or None or have an __index__ method" @@ -83,7 +73,7 @@ def test_range_slice_day(self): def test_range_slice_seconds(self): # GH#6716 - didx = pd.date_range(start="2013/01/01 09:00:00", freq="S", periods=4000) + didx = date_range(start="2013/01/01 09:00:00", freq="S", periods=4000) pidx = period_range(start="2013/01/01 09:00:00", freq="S", periods=4000) msg = "slice indices must be integers or None or have an __index__ method" @@ -113,7 +103,7 @@ def test_range_slice_seconds(self): def test_range_slice_outofbounds(self): # GH#5407 - didx = pd.date_range(start="2013/10/01", freq="D", periods=10) + didx = date_range(start="2013/10/01", freq="D", periods=10) pidx = period_range(start="2013/10/01", freq="D", periods=10) for idx in [didx, pidx]: @@ -131,10 +121,10 @@ def test_range_slice_outofbounds(self): def test_partial_slice_doesnt_require_monotonicity(self): # See also: DatetimeIndex test ofm the same name - dti = pd.date_range("2014-01-01", periods=30, freq="30D") + dti = date_range("2014-01-01", periods=30, freq="30D") pi = dti.to_period("D") - ser_montonic = pd.Series(np.arange(30), index=pi) + ser_montonic = Series(np.arange(30), index=pi) shuffler = list(range(0, 30, 2)) + list(range(1, 31, 2)) ser = ser_montonic[shuffler] diff --git a/pandas/tests/indexes/timedeltas/test_partial_slicing.py b/pandas/tests/indexes/timedeltas/test_partial_slicing.py index 10ad521ce4f76..89a4aa2062d04 100644 --- a/pandas/tests/indexes/timedeltas/test_partial_slicing.py +++ b/pandas/tests/indexes/timedeltas/test_partial_slicing.py @@ -1,8 +1,7 @@ import numpy as np import pytest -import pandas as pd -from pandas import Series, Timedelta, timedelta_range +from pandas import IndexSlice, Series, Timedelta, timedelta_range import pandas._testing as tm @@ -49,7 +48,7 @@ def test_partial_slice_high_reso(self): def test_slice_with_negative_step(self): ts = Series(np.arange(20), timedelta_range("0", periods=20, freq="H")) - SLC = pd.IndexSlice + SLC = IndexSlice def assert_slices_equivalent(l_slc, i_slc): expected = ts.iloc[i_slc] @@ -76,12 +75,3 @@ def assert_slices_equivalent(l_slc, i_slc): ) assert_slices_equivalent(SLC["7 hours":"15 hours":-1], SLC[0:0:-1]) - - def test_slice_with_zero_step_raises(self): - ts = Series(np.arange(20), timedelta_range("0", periods=20, freq="H")) - with pytest.raises(ValueError, match="slice step cannot be zero"): - ts[::0] - with pytest.raises(ValueError, match="slice step cannot be zero"): - ts.loc[::0] - with pytest.raises(ValueError, match="slice step cannot be zero"): - ts.loc[::0] diff --git a/pandas/tests/series/indexing/test_indexing.py b/pandas/tests/series/indexing/test_indexing.py index c2b5117d395f9..d2b5d1f51e07c 100644 --- a/pandas/tests/series/indexing/test_indexing.py +++ b/pandas/tests/series/indexing/test_indexing.py @@ -8,7 +8,17 @@ from pandas.core.dtypes.common import is_scalar import pandas as pd -from pandas import Categorical, DataFrame, MultiIndex, Series, Timedelta, Timestamp +from pandas import ( + Categorical, + DataFrame, + MultiIndex, + Series, + Timedelta, + Timestamp, + date_range, + period_range, + timedelta_range, +) import pandas._testing as tm from pandas.tseries.offsets import BDay @@ -877,3 +887,22 @@ def test_getitem_unrecognized_scalar(): result = ser[key] assert result == 2 + + +@pytest.mark.parametrize( + "index", + [ + date_range("2014-01-01", periods=20, freq="MS"), + period_range("2014-01", periods=20, freq="M"), + timedelta_range("0", periods=20, freq="H"), + ], +) +def test_slice_with_zero_step_raises(index): + ts = Series(np.arange(20), index) + + with pytest.raises(ValueError, match="slice step cannot be zero"): + ts[::0] + with pytest.raises(ValueError, match="slice step cannot be zero"): + ts.loc[::0] + with pytest.raises(ValueError, match="slice step cannot be zero"): + ts.iloc[::0] From 39d6c829f6304534e36623540a7491713ad1c869 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Wed, 29 Apr 2020 10:18:54 -0700 Subject: [PATCH 2/3] parametrize tests --- .../indexes/datetimes/test_partial_slicing.py | 31 ----------------- .../indexes/period/test_partial_slicing.py | 26 +-------------- .../timedeltas/test_partial_slicing.py | 32 +----------------- pandas/tests/series/indexing/test_indexing.py | 33 +++++++++++++++++++ 4 files changed, 35 insertions(+), 87 deletions(-) diff --git a/pandas/tests/indexes/datetimes/test_partial_slicing.py b/pandas/tests/indexes/datetimes/test_partial_slicing.py index 32533263edd3c..635470b930252 100644 --- a/pandas/tests/indexes/datetimes/test_partial_slicing.py +++ b/pandas/tests/indexes/datetimes/test_partial_slicing.py @@ -10,7 +10,6 @@ DataFrame, DatetimeIndex, Index, - IndexSlice, Series, Timedelta, Timestamp, @@ -21,36 +20,6 @@ class TestSlicing: - def test_slice_with_negative_step(self): - ts = Series(np.arange(20), date_range("2014-01-01", periods=20, freq="MS")) - SLC = IndexSlice - - def assert_slices_equivalent(l_slc, i_slc): - expected = ts.iloc[i_slc] - - tm.assert_series_equal(ts[l_slc], expected) - tm.assert_series_equal(ts.loc[l_slc], expected) - tm.assert_series_equal(ts.loc[l_slc], expected) - - assert_slices_equivalent(SLC[Timestamp("2014-10-01") :: -1], SLC[9::-1]) - assert_slices_equivalent(SLC["2014-10-01"::-1], SLC[9::-1]) - - assert_slices_equivalent(SLC[: Timestamp("2014-10-01") : -1], SLC[:8:-1]) - assert_slices_equivalent(SLC[:"2014-10-01":-1], SLC[:8:-1]) - - assert_slices_equivalent(SLC["2015-02-01":"2014-10-01":-1], SLC[13:8:-1]) - assert_slices_equivalent( - SLC[Timestamp("2015-02-01") : Timestamp("2014-10-01") : -1], SLC[13:8:-1] - ) - assert_slices_equivalent( - SLC["2015-02-01" : Timestamp("2014-10-01") : -1], SLC[13:8:-1] - ) - assert_slices_equivalent( - SLC[Timestamp("2015-02-01") : "2014-10-01" : -1], SLC[13:8:-1] - ) - - assert_slices_equivalent(SLC["2014-10-01":"2015-02-01":-1], SLC[0:0:-1]) - def test_monotone_DTI_indexing_bug(self): # GH 19362 # Testing accessing the first element in a monotonic descending diff --git a/pandas/tests/indexes/period/test_partial_slicing.py b/pandas/tests/indexes/period/test_partial_slicing.py index d2d2b38dcf1d2..ad97f3e94f128 100644 --- a/pandas/tests/indexes/period/test_partial_slicing.py +++ b/pandas/tests/indexes/period/test_partial_slicing.py @@ -1,35 +1,11 @@ import numpy as np import pytest -from pandas import DataFrame, IndexSlice, Period, Series, date_range, period_range +from pandas import DataFrame, Series, date_range, period_range import pandas._testing as tm class TestPeriodIndex: - def test_slice_with_negative_step(self): - ts = Series(np.arange(20), period_range("2014-01", periods=20, freq="M")) - SLC = IndexSlice - - def assert_slices_equivalent(l_slc, i_slc): - tm.assert_series_equal(ts[l_slc], ts.iloc[i_slc]) - tm.assert_series_equal(ts.loc[l_slc], ts.iloc[i_slc]) - tm.assert_series_equal(ts.loc[l_slc], ts.iloc[i_slc]) - - assert_slices_equivalent(SLC[Period("2014-10") :: -1], SLC[9::-1]) - assert_slices_equivalent(SLC["2014-10"::-1], SLC[9::-1]) - - assert_slices_equivalent(SLC[: Period("2014-10") : -1], SLC[:8:-1]) - assert_slices_equivalent(SLC[:"2014-10":-1], SLC[:8:-1]) - - assert_slices_equivalent(SLC["2015-02":"2014-10":-1], SLC[13:8:-1]) - assert_slices_equivalent( - SLC[Period("2015-02") : Period("2014-10") : -1], SLC[13:8:-1] - ) - assert_slices_equivalent(SLC["2015-02" : Period("2014-10") : -1], SLC[13:8:-1]) - assert_slices_equivalent(SLC[Period("2015-02") : "2014-10" : -1], SLC[13:8:-1]) - - assert_slices_equivalent(SLC["2014-10":"2015-02":-1], SLC[:0]) - def test_pindex_slice_index(self): pi = period_range(start="1/1/10", end="12/31/12", freq="M") s = Series(np.random.rand(len(pi)), index=pi) diff --git a/pandas/tests/indexes/timedeltas/test_partial_slicing.py b/pandas/tests/indexes/timedeltas/test_partial_slicing.py index 89a4aa2062d04..e5f509acf4734 100644 --- a/pandas/tests/indexes/timedeltas/test_partial_slicing.py +++ b/pandas/tests/indexes/timedeltas/test_partial_slicing.py @@ -1,7 +1,7 @@ import numpy as np import pytest -from pandas import IndexSlice, Series, Timedelta, timedelta_range +from pandas import Series, timedelta_range import pandas._testing as tm @@ -45,33 +45,3 @@ def test_partial_slice_high_reso(self): result = s["1 days, 10:11:12.001001"] assert result == s.iloc[1001] - - def test_slice_with_negative_step(self): - ts = Series(np.arange(20), timedelta_range("0", periods=20, freq="H")) - SLC = IndexSlice - - def assert_slices_equivalent(l_slc, i_slc): - expected = ts.iloc[i_slc] - - tm.assert_series_equal(ts[l_slc], expected) - tm.assert_series_equal(ts.loc[l_slc], expected) - tm.assert_series_equal(ts.loc[l_slc], expected) - - assert_slices_equivalent(SLC[Timedelta(hours=7) :: -1], SLC[7::-1]) - assert_slices_equivalent(SLC["7 hours"::-1], SLC[7::-1]) - - assert_slices_equivalent(SLC[: Timedelta(hours=7) : -1], SLC[:6:-1]) - assert_slices_equivalent(SLC[:"7 hours":-1], SLC[:6:-1]) - - assert_slices_equivalent(SLC["15 hours":"7 hours":-1], SLC[15:6:-1]) - assert_slices_equivalent( - SLC[Timedelta(hours=15) : Timedelta(hours=7) : -1], SLC[15:6:-1] - ) - assert_slices_equivalent( - SLC["15 hours" : Timedelta(hours=7) : -1], SLC[15:6:-1] - ) - assert_slices_equivalent( - SLC[Timedelta(hours=15) : "7 hours" : -1], SLC[15:6:-1] - ) - - assert_slices_equivalent(SLC["7 hours":"15 hours":-1], SLC[0:0:-1]) diff --git a/pandas/tests/series/indexing/test_indexing.py b/pandas/tests/series/indexing/test_indexing.py index d2b5d1f51e07c..3674e59c5bd6f 100644 --- a/pandas/tests/series/indexing/test_indexing.py +++ b/pandas/tests/series/indexing/test_indexing.py @@ -11,6 +11,7 @@ from pandas import ( Categorical, DataFrame, + IndexSlice, MultiIndex, Series, Timedelta, @@ -906,3 +907,35 @@ def test_slice_with_zero_step_raises(index): ts.loc[::0] with pytest.raises(ValueError, match="slice step cannot be zero"): ts.iloc[::0] + + +@pytest.mark.parametrize( + "index", + [ + date_range("2014-01-01", periods=20, freq="MS"), + period_range("2014-01", periods=20, freq="M"), + timedelta_range("0", periods=20, freq="H"), + ], +) +def test_slice_with_negative_step(index): + def assert_slices_equivalent(l_slc, i_slc): + expected = ts.iloc[i_slc] + + tm.assert_series_equal(ts[l_slc], expected) + tm.assert_series_equal(ts.loc[l_slc], expected) + tm.assert_series_equal(ts.loc[l_slc], expected) + + keystr1 = str(index[9]) + keystr2 = str(index[13]) + box = type(index[0]) + + ts = Series(np.arange(20), index) + SLC = IndexSlice + + for key in [keystr1, box(keystr1)]: + assert_slices_equivalent(SLC[key::-1], SLC[9::-1]) + assert_slices_equivalent(SLC[:key:-1], SLC[:8:-1]) + + for key2 in [keystr2, box(keystr2)]: + assert_slices_equivalent(SLC[key2:key:-1], SLC[13:8:-1]) + assert_slices_equivalent(SLC[key:key2:-1], SLC[0:0:-1]) From 4f3f0d256822bab817459d0e6cc72dd6a046c44b Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Wed, 29 Apr 2020 10:27:19 -0700 Subject: [PATCH 3/3] parametrize --- .../indexes/period/test_partial_slicing.py | 137 +++++++++--------- 1 file changed, 66 insertions(+), 71 deletions(-) diff --git a/pandas/tests/indexes/period/test_partial_slicing.py b/pandas/tests/indexes/period/test_partial_slicing.py index ad97f3e94f128..aa99207261e4e 100644 --- a/pandas/tests/indexes/period/test_partial_slicing.py +++ b/pandas/tests/indexes/period/test_partial_slicing.py @@ -16,84 +16,79 @@ def test_pindex_slice_index(self): exp = s[12:24] tm.assert_series_equal(res, exp) - def test_range_slice_day(self): + @pytest.mark.parametrize("make_range", [date_range, period_range]) + def test_range_slice_day(self, make_range): # GH#6716 - didx = date_range(start="2013/01/01", freq="D", periods=400) - pidx = period_range(start="2013/01/01", freq="D", periods=400) + idx = make_range(start="2013/01/01", freq="D", periods=400) msg = "slice indices must be integers or None or have an __index__ method" - for idx in [didx, pidx]: - # slices against index should raise IndexError - values = [ - "2014", - "2013/02", - "2013/01/02", - "2013/02/01 9H", - "2013/02/01 09:00", - ] - for v in values: - with pytest.raises(TypeError, match=msg): - idx[v:] - - s = Series(np.random.rand(len(idx)), index=idx) - - tm.assert_series_equal(s["2013/01/02":], s[1:]) - tm.assert_series_equal(s["2013/01/02":"2013/01/05"], s[1:5]) - tm.assert_series_equal(s["2013/02":], s[31:]) - tm.assert_series_equal(s["2014":], s[365:]) - - invalid = ["2013/02/01 9H", "2013/02/01 09:00"] - for v in invalid: - with pytest.raises(TypeError, match=msg): - idx[v:] - - def test_range_slice_seconds(self): + # slices against index should raise IndexError + values = [ + "2014", + "2013/02", + "2013/01/02", + "2013/02/01 9H", + "2013/02/01 09:00", + ] + for v in values: + with pytest.raises(TypeError, match=msg): + idx[v:] + + s = Series(np.random.rand(len(idx)), index=idx) + + tm.assert_series_equal(s["2013/01/02":], s[1:]) + tm.assert_series_equal(s["2013/01/02":"2013/01/05"], s[1:5]) + tm.assert_series_equal(s["2013/02":], s[31:]) + tm.assert_series_equal(s["2014":], s[365:]) + + invalid = ["2013/02/01 9H", "2013/02/01 09:00"] + for v in invalid: + with pytest.raises(TypeError, match=msg): + idx[v:] + + @pytest.mark.parametrize("make_range", [date_range, period_range]) + def test_range_slice_seconds(self, make_range): # GH#6716 - didx = date_range(start="2013/01/01 09:00:00", freq="S", periods=4000) - pidx = period_range(start="2013/01/01 09:00:00", freq="S", periods=4000) + idx = make_range(start="2013/01/01 09:00:00", freq="S", periods=4000) msg = "slice indices must be integers or None or have an __index__ method" - for idx in [didx, pidx]: - # slices against index should raise IndexError - values = [ - "2014", - "2013/02", - "2013/01/02", - "2013/02/01 9H", - "2013/02/01 09:00", - ] - for v in values: - with pytest.raises(TypeError, match=msg): - idx[v:] - - s = Series(np.random.rand(len(idx)), index=idx) - - tm.assert_series_equal(s["2013/01/01 09:05":"2013/01/01 09:10"], s[300:660]) - tm.assert_series_equal( - s["2013/01/01 10:00":"2013/01/01 10:05"], s[3600:3960] - ) - tm.assert_series_equal(s["2013/01/01 10H":], s[3600:]) - tm.assert_series_equal(s[:"2013/01/01 09:30"], s[:1860]) - for d in ["2013/01/01", "2013/01", "2013"]: - tm.assert_series_equal(s[d:], s) - - def test_range_slice_outofbounds(self): + # slices against index should raise IndexError + values = [ + "2014", + "2013/02", + "2013/01/02", + "2013/02/01 9H", + "2013/02/01 09:00", + ] + for v in values: + with pytest.raises(TypeError, match=msg): + idx[v:] + + s = Series(np.random.rand(len(idx)), index=idx) + + tm.assert_series_equal(s["2013/01/01 09:05":"2013/01/01 09:10"], s[300:660]) + tm.assert_series_equal(s["2013/01/01 10:00":"2013/01/01 10:05"], s[3600:3960]) + tm.assert_series_equal(s["2013/01/01 10H":], s[3600:]) + tm.assert_series_equal(s[:"2013/01/01 09:30"], s[:1860]) + for d in ["2013/01/01", "2013/01", "2013"]: + tm.assert_series_equal(s[d:], s) + + @pytest.mark.parametrize("make_range", [date_range, period_range]) + def test_range_slice_outofbounds(self, make_range): # GH#5407 - didx = date_range(start="2013/10/01", freq="D", periods=10) - pidx = period_range(start="2013/10/01", freq="D", periods=10) - - for idx in [didx, pidx]: - df = DataFrame(dict(units=[100 + i for i in range(10)]), index=idx) - empty = DataFrame(index=type(idx)([], freq="D"), columns=["units"]) - empty["units"] = empty["units"].astype("int64") - - tm.assert_frame_equal(df["2013/09/01":"2013/09/30"], empty) - tm.assert_frame_equal(df["2013/09/30":"2013/10/02"], df.iloc[:2]) - tm.assert_frame_equal(df["2013/10/01":"2013/10/02"], df.iloc[:2]) - tm.assert_frame_equal(df["2013/10/02":"2013/09/30"], empty) - tm.assert_frame_equal(df["2013/10/15":"2013/10/17"], empty) - tm.assert_frame_equal(df["2013-06":"2013-09"], empty) - tm.assert_frame_equal(df["2013-11":"2013-12"], empty) + idx = make_range(start="2013/10/01", freq="D", periods=10) + + df = DataFrame(dict(units=[100 + i for i in range(10)]), index=idx) + empty = DataFrame(index=type(idx)([], freq="D"), columns=["units"]) + empty["units"] = empty["units"].astype("int64") + + tm.assert_frame_equal(df["2013/09/01":"2013/09/30"], empty) + tm.assert_frame_equal(df["2013/09/30":"2013/10/02"], df.iloc[:2]) + tm.assert_frame_equal(df["2013/10/01":"2013/10/02"], df.iloc[:2]) + tm.assert_frame_equal(df["2013/10/02":"2013/09/30"], empty) + tm.assert_frame_equal(df["2013/10/15":"2013/10/17"], empty) + tm.assert_frame_equal(df["2013-06":"2013-09"], empty) + tm.assert_frame_equal(df["2013-11":"2013-12"], empty) def test_partial_slice_doesnt_require_monotonicity(self): # See also: DatetimeIndex test ofm the same name