From 4ad0d62bd9c347853ab1735561357158bbe32b55 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Sun, 11 Feb 2018 14:46:30 -0800 Subject: [PATCH 1/7] fixup formatting --- .../tests/indexes/period/test_arithmetic.py | 139 ++++++++---------- 1 file changed, 64 insertions(+), 75 deletions(-) diff --git a/pandas/tests/indexes/period/test_arithmetic.py b/pandas/tests/indexes/period/test_arithmetic.py index 81171920f635f..67b91b21e326c 100644 --- a/pandas/tests/indexes/period/test_arithmetic.py +++ b/pandas/tests/indexes/period/test_arithmetic.py @@ -203,7 +203,7 @@ def test_pi_radd_offset_array(self): expected = pd.PeriodIndex([pd.Period('2015Q2'), pd.Period('2015Q4')]) tm.assert_index_equal(res, expected) - def test_add_iadd(self): + def test_pi_add_iadd_pi_raises(self): rng = pd.period_range('1/1/2000', freq='D', periods=5) other = pd.period_range('1/6/2000', freq='D', periods=5) @@ -214,6 +214,7 @@ def test_add_iadd(self): with pytest.raises(TypeError): rng += other + def test_add_iadd(self): # offset # DateOffset rng = pd.period_range('2014', '2024', freq='A') @@ -228,8 +229,7 @@ def test_add_iadd(self): timedelta(365), Timedelta(days=365)]: msg = ('Input has different freq(=.+)? ' 'from PeriodIndex\\(freq=A-DEC\\)') - with tm.assert_raises_regex( - period.IncompatibleFrequency, msg): + with tm.assert_raises_regex(period.IncompatibleFrequency, msg): rng + o rng = pd.period_range('2014-01', '2016-12', freq='M') @@ -244,8 +244,7 @@ def test_add_iadd(self): timedelta(365), Timedelta(days=365)]: rng = pd.period_range('2014-01', '2016-12', freq='M') msg = 'Input has different freq(=.+)? from PeriodIndex\\(freq=M\\)' - with tm.assert_raises_regex( - period.IncompatibleFrequency, msg): + with tm.assert_raises_regex(period.IncompatibleFrequency, msg): rng + o # Tick @@ -266,8 +265,7 @@ def test_add_iadd(self): timedelta(hours=23), Timedelta('23:00:00')]: rng = pd.period_range('2014-05-01', '2014-05-15', freq='D') msg = 'Input has different freq(=.+)? from PeriodIndex\\(freq=D\\)' - with tm.assert_raises_regex( - period.IncompatibleFrequency, msg): + with tm.assert_raises_regex(period.IncompatibleFrequency, msg): rng + o offsets = [pd.offsets.Hour(2), timedelta(hours=2), @@ -289,11 +287,9 @@ def test_add_iadd(self): rng = pd.period_range('2014-01-01 10:00', '2014-01-05 10:00', freq='H') msg = 'Input has different freq(=.+)? from PeriodIndex\\(freq=H\\)' - with tm.assert_raises_regex( - period.IncompatibleFrequency, msg): + with tm.assert_raises_regex(period.IncompatibleFrequency, msg): rng + delta - with tm.assert_raises_regex( - period.IncompatibleFrequency, msg): + with tm.assert_raises_regex(period.IncompatibleFrequency, msg): rng += delta def test_pi_add_int(self, one): @@ -313,8 +309,7 @@ def test_sub(self, five): exp = rng + (-five) tm.assert_index_equal(result, exp) - def test_sub_isub(self): - + def test_pi_sub_isub_pi_raises(self): # previously performed setop, now raises TypeError (GH14164) # TODO needs to wait on #13077 for decision on result type rng = pd.period_range('1/1/2000', freq='D', periods=5) @@ -326,6 +321,7 @@ def test_sub_isub(self): with pytest.raises(TypeError): rng -= other + def test_sub_isub(self): # offset # DateOffset rng = pd.period_range('2014', '2024', freq='A') @@ -357,8 +353,7 @@ def test_sub_isub(self): timedelta(365)]: rng = pd.period_range('2014-01', '2016-12', freq='M') msg = 'Input has different freq(=.+)? from PeriodIndex\\(freq=M\\)' - with tm.assert_raises_regex( - period.IncompatibleFrequency, msg): + with tm.assert_raises_regex(period.IncompatibleFrequency, msg): rng - o # Tick @@ -378,8 +373,7 @@ def test_sub_isub(self): timedelta(hours=23)]: rng = pd.period_range('2014-05-01', '2014-05-15', freq='D') msg = 'Input has different freq(=.+)? from PeriodIndex\\(freq=D\\)' - with tm.assert_raises_regex( - period.IncompatibleFrequency, msg): + with tm.assert_raises_regex(period.IncompatibleFrequency, msg): rng - o offsets = [pd.offsets.Hour(2), timedelta(hours=2), @@ -400,11 +394,9 @@ def test_sub_isub(self): rng = pd.period_range('2014-01-01 10:00', '2014-01-05 10:00', freq='H') msg = 'Input has different freq(=.+)? from PeriodIndex\\(freq=H\\)' - with tm.assert_raises_regex( - period.IncompatibleFrequency, msg): + with tm.assert_raises_regex(period.IncompatibleFrequency, msg): rng + delta - with tm.assert_raises_regex( - period.IncompatibleFrequency, msg): + with tm.assert_raises_regex(period.IncompatibleFrequency, msg): rng += delta # int @@ -419,18 +411,18 @@ def test_sub_isub(self): # PeriodIndex.shift is used by __add__ and __sub__ def test_pi_shift_ndarray(self): - idx = PeriodIndex(['2011-01', '2011-02', 'NaT', - '2011-04'], freq='M', name='idx') + idx = PeriodIndex(['2011-01', '2011-02', 'NaT', '2011-04'], + freq='M', name='idx') result = idx.shift(np.array([1, 2, 3, 4])) - expected = PeriodIndex(['2011-02', '2011-04', 'NaT', - '2011-08'], freq='M', name='idx') + expected = PeriodIndex(['2011-02', '2011-04', 'NaT', '2011-08'], + freq='M', name='idx') tm.assert_index_equal(result, expected) - idx = PeriodIndex(['2011-01', '2011-02', 'NaT', - '2011-04'], freq='M', name='idx') + idx = PeriodIndex(['2011-01', '2011-02', 'NaT', '2011-04'], + freq='M', name='idx') result = idx.shift(np.array([1, -2, 3, -4])) - expected = PeriodIndex(['2011-02', '2010-12', 'NaT', - '2010-12'], freq='M', name='idx') + expected = PeriodIndex(['2011-02', '2010-12', 'NaT', '2010-12'], + freq='M', name='idx') tm.assert_index_equal(result, expected) def test_shift(self): @@ -489,11 +481,11 @@ def test_shift_corner_cases(self): tm.assert_index_equal(idx.shift(-3), exp) def test_shift_nat(self): - idx = PeriodIndex(['2011-01', '2011-02', 'NaT', - '2011-04'], freq='M', name='idx') + idx = PeriodIndex(['2011-01', '2011-02', 'NaT', '2011-04'], + freq='M', name='idx') result = idx.shift(1) - expected = PeriodIndex(['2011-02', '2011-03', 'NaT', - '2011-05'], freq='M', name='idx') + expected = PeriodIndex(['2011-02', '2011-03', 'NaT', '2011-05'], + freq='M', name='idx') tm.assert_index_equal(result, expected) assert result.name == expected.name @@ -519,18 +511,18 @@ def _check(self, values, func, expected): # comp op results in bool tm.assert_numpy_array_equal(result, expected) - s = pd.Series(values) - result = func(s) + ser = pd.Series(values) + result = func(ser) exp = pd.Series(expected, name=values.name) tm.assert_series_equal(result, exp) def test_pi_ops(self): - idx = PeriodIndex(['2011-01', '2011-02', '2011-03', - '2011-04'], freq='M', name='idx') + idx = PeriodIndex(['2011-01', '2011-02', '2011-03', '2011-04'], + freq='M', name='idx') - expected = PeriodIndex(['2011-03', '2011-04', - '2011-05', '2011-06'], freq='M', name='idx') + expected = PeriodIndex(['2011-03', '2011-04', '2011-05', '2011-06'], + freq='M', name='idx') self._check(idx, lambda x: x + 2, expected) self._check(idx, lambda x: 2 + x, expected) @@ -544,13 +536,13 @@ def test_pi_ops(self): tm.assert_index_equal(result, exp) def test_pi_ops_errors(self): - idx = PeriodIndex(['2011-01', '2011-02', '2011-03', - '2011-04'], freq='M', name='idx') - s = pd.Series(idx) + idx = PeriodIndex(['2011-01', '2011-02', '2011-03', '2011-04'], + freq='M', name='idx') + ser = pd.Series(idx) msg = r"unsupported operand type\(s\)" - for obj in [idx, s]: + for obj in [idx, ser]: for ng in ["str", 1.5]: with tm.assert_raises_regex(TypeError, msg): obj + ng @@ -581,10 +573,10 @@ def test_pi_ops_errors(self): np.subtract(ng, obj) def test_pi_ops_nat(self): - idx = PeriodIndex(['2011-01', '2011-02', 'NaT', - '2011-04'], freq='M', name='idx') - expected = PeriodIndex(['2011-03', '2011-04', - 'NaT', '2011-06'], freq='M', name='idx') + idx = PeriodIndex(['2011-01', '2011-02', 'NaT', '2011-04'], + freq='M', name='idx') + expected = PeriodIndex(['2011-03', '2011-04', 'NaT', '2011-06'], + freq='M', name='idx') self._check(idx, lambda x: x + 2, expected) self._check(idx, lambda x: 2 + x, expected) self._check(idx, lambda x: np.add(x, 2), expected) @@ -593,10 +585,10 @@ def test_pi_ops_nat(self): self._check(idx + 2, lambda x: np.subtract(x, 2), idx) # freq with mult - idx = PeriodIndex(['2011-01', '2011-02', 'NaT', - '2011-04'], freq='2M', name='idx') - expected = PeriodIndex(['2011-07', '2011-08', - 'NaT', '2011-10'], freq='2M', name='idx') + idx = PeriodIndex(['2011-01', '2011-02', 'NaT', '2011-04'], + freq='2M', name='idx') + expected = PeriodIndex(['2011-07', '2011-08', 'NaT', '2011-10'], + freq='2M', name='idx') self._check(idx, lambda x: x + 3, expected) self._check(idx, lambda x: 3 + x, expected) self._check(idx, lambda x: np.add(x, 3), expected) @@ -605,26 +597,26 @@ def test_pi_ops_nat(self): self._check(idx + 3, lambda x: np.subtract(x, 3), idx) def test_pi_ops_array_int(self): - idx = PeriodIndex(['2011-01', '2011-02', 'NaT', - '2011-04'], freq='M', name='idx') + idx = PeriodIndex(['2011-01', '2011-02', 'NaT', '2011-04'], + freq='M', name='idx') f = lambda x: x + np.array([1, 2, 3, 4]) - exp = PeriodIndex(['2011-02', '2011-04', 'NaT', - '2011-08'], freq='M', name='idx') + exp = PeriodIndex(['2011-02', '2011-04', 'NaT', '2011-08'], + freq='M', name='idx') self._check(idx, f, exp) f = lambda x: np.add(x, np.array([4, -1, 1, 2])) - exp = PeriodIndex(['2011-05', '2011-01', 'NaT', - '2011-06'], freq='M', name='idx') + exp = PeriodIndex(['2011-05', '2011-01', 'NaT', '2011-06'], + freq='M', name='idx') self._check(idx, f, exp) f = lambda x: x - np.array([1, 2, 3, 4]) - exp = PeriodIndex(['2010-12', '2010-12', 'NaT', - '2010-12'], freq='M', name='idx') + exp = PeriodIndex(['2010-12', '2010-12', 'NaT', '2010-12'], + freq='M', name='idx') self._check(idx, f, exp) f = lambda x: np.subtract(x, np.array([3, 2, 3, -2])) - exp = PeriodIndex(['2010-10', '2010-12', 'NaT', - '2011-06'], freq='M', name='idx') + exp = PeriodIndex(['2010-10', '2010-12', 'NaT', '2011-06'], + freq='M', name='idx') self._check(idx, f, exp) def test_pi_ops_offset(self): @@ -648,29 +640,26 @@ def test_pi_ops_offset(self): def test_pi_offset_errors(self): idx = PeriodIndex(['2011-01-01', '2011-02-01', '2011-03-01', '2011-04-01'], freq='D', name='idx') - s = pd.Series(idx) + ser = pd.Series(idx) # Series op is applied per Period instance, thus error is raised # from Period msg_idx = r"Input has different freq from PeriodIndex\(freq=D\)" msg_s = r"Input cannot be converted to Period\(freq=D\)" - for obj, msg in [(idx, msg_idx), (s, msg_s)]: - with tm.assert_raises_regex( - period.IncompatibleFrequency, msg): + for obj, msg in [(idx, msg_idx), (ser, msg_s)]: + with tm.assert_raises_regex(period.IncompatibleFrequency, msg): obj + pd.offsets.Hour(2) - with tm.assert_raises_regex( - period.IncompatibleFrequency, msg): + with tm.assert_raises_regex(period.IncompatibleFrequency, msg): pd.offsets.Hour(2) + obj - with tm.assert_raises_regex( - period.IncompatibleFrequency, msg): + with tm.assert_raises_regex(period.IncompatibleFrequency, msg): obj - pd.offsets.Hour(2) def test_pi_sub_period(self): # GH 13071 - idx = PeriodIndex(['2011-01', '2011-02', '2011-03', - '2011-04'], freq='M', name='idx') + idx = PeriodIndex(['2011-01', '2011-02', '2011-03', '2011-04'], + freq='M', name='idx') result = idx - pd.Period('2012-01', freq='M') exp = pd.Index([-12, -11, -10, -9], name='idx') @@ -695,16 +684,16 @@ def test_pi_sub_period(self): def test_pi_sub_pdnat(self): # GH 13071 - idx = PeriodIndex(['2011-01', '2011-02', 'NaT', - '2011-04'], freq='M', name='idx') + idx = PeriodIndex(['2011-01', '2011-02', 'NaT', '2011-04'], + freq='M', name='idx') exp = pd.TimedeltaIndex([pd.NaT] * 4, name='idx') tm.assert_index_equal(pd.NaT - idx, exp) tm.assert_index_equal(idx - pd.NaT, exp) def test_pi_sub_period_nat(self): # GH 13071 - idx = PeriodIndex(['2011-01', 'NaT', '2011-03', - '2011-04'], freq='M', name='idx') + idx = PeriodIndex(['2011-01', 'NaT', '2011-03', '2011-04'], + freq='M', name='idx') result = idx - pd.Period('2012-01', freq='M') exp = pd.Index([-12, np.nan, -10, -9], name='idx') From 2281d0f9bb963aaa5a4a34b42a709251be4015e3 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Mon, 12 Feb 2018 08:52:44 -0800 Subject: [PATCH 2/7] parametrize PeriodIndex tests --- .../tests/indexes/period/test_arithmetic.py | 401 +++++++++++------- pandas/tests/indexes/period/test_astype.py | 99 +++++ pandas/tests/indexes/period/test_ops.py | 36 -- pandas/tests/indexes/period/test_period.py | 60 +-- 4 files changed, 336 insertions(+), 260 deletions(-) create mode 100644 pandas/tests/indexes/period/test_astype.py diff --git a/pandas/tests/indexes/period/test_arithmetic.py b/pandas/tests/indexes/period/test_arithmetic.py index 67b91b21e326c..b97f2051e930e 100644 --- a/pandas/tests/indexes/period/test_arithmetic.py +++ b/pandas/tests/indexes/period/test_arithmetic.py @@ -12,6 +12,13 @@ class TestPeriodIndexComparisons(object): + def test_pi_cmp_period(self): + idx = period_range('2007-01', periods=20, freq='M') + + result = idx < idx[10] + exp = idx.values < idx.values[10] + tm.assert_numpy_array_equal(result, exp) + @pytest.mark.parametrize('freq', ['M', '2M', '3M']) def test_pi_cmp_pi(self, freq): base = PeriodIndex(['2011-01', '2011-02', '2011-03', '2011-04'], @@ -148,32 +155,35 @@ def test_pi_cmp_nat_mismatched_freq_raises(self, freq): idx1 == diff # TODO: De-duplicate with test_pi_cmp_nat - def test_comp_nat(self): + @pytest.mark.parametrize('dtype', [object, None]) + def test_comp_nat(self, dtype): left = pd.PeriodIndex([pd.Period('2011-01-01'), pd.NaT, pd.Period('2011-01-03')]) right = pd.PeriodIndex([pd.NaT, pd.NaT, pd.Period('2011-01-03')]) - for lhs, rhs in [(left, right), - (left.astype(object), right.astype(object))]: - result = lhs == rhs - expected = np.array([False, False, True]) - tm.assert_numpy_array_equal(result, expected) + if dtype is not None: + left = left.astype(dtype) + right = right.dtype - result = lhs != rhs - expected = np.array([True, True, False]) - tm.assert_numpy_array_equal(result, expected) + result = left == right + expected = np.array([False, False, True]) + tm.assert_numpy_array_equal(result, expected) + + result = left != right + expected = np.array([True, True, False]) + tm.assert_numpy_array_equal(result, expected) - expected = np.array([False, False, False]) - tm.assert_numpy_array_equal(lhs == pd.NaT, expected) - tm.assert_numpy_array_equal(pd.NaT == rhs, expected) + expected = np.array([False, False, False]) + tm.assert_numpy_array_equal(left == pd.NaT, expected) + tm.assert_numpy_array_equal(pd.NaT == right, expected) - expected = np.array([True, True, True]) - tm.assert_numpy_array_equal(lhs != pd.NaT, expected) - tm.assert_numpy_array_equal(pd.NaT != lhs, expected) + expected = np.array([True, True, True]) + tm.assert_numpy_array_equal(left != pd.NaT, expected) + tm.assert_numpy_array_equal(pd.NaT != left, expected) - expected = np.array([False, False, False]) - tm.assert_numpy_array_equal(lhs < pd.NaT, expected) - tm.assert_numpy_array_equal(pd.NaT > lhs, expected) + expected = np.array([False, False, False]) + tm.assert_numpy_array_equal(left < pd.NaT, expected) + tm.assert_numpy_array_equal(pd.NaT > left, expected) class TestPeriodIndexArithmetic(object): @@ -214,85 +224,7 @@ def test_pi_add_iadd_pi_raises(self): with pytest.raises(TypeError): rng += other - def test_add_iadd(self): - # offset - # DateOffset - rng = pd.period_range('2014', '2024', freq='A') - result = rng + pd.offsets.YearEnd(5) - expected = pd.period_range('2019', '2029', freq='A') - tm.assert_index_equal(result, expected) - rng += pd.offsets.YearEnd(5) - tm.assert_index_equal(rng, expected) - - for o in [pd.offsets.YearBegin(2), pd.offsets.MonthBegin(1), - pd.offsets.Minute(), np.timedelta64(365, 'D'), - timedelta(365), Timedelta(days=365)]: - msg = ('Input has different freq(=.+)? ' - 'from PeriodIndex\\(freq=A-DEC\\)') - with tm.assert_raises_regex(period.IncompatibleFrequency, msg): - rng + o - - rng = pd.period_range('2014-01', '2016-12', freq='M') - result = rng + pd.offsets.MonthEnd(5) - expected = pd.period_range('2014-06', '2017-05', freq='M') - tm.assert_index_equal(result, expected) - rng += pd.offsets.MonthEnd(5) - tm.assert_index_equal(rng, expected) - - for o in [pd.offsets.YearBegin(2), pd.offsets.MonthBegin(1), - pd.offsets.Minute(), np.timedelta64(365, 'D'), - timedelta(365), Timedelta(days=365)]: - rng = pd.period_range('2014-01', '2016-12', freq='M') - msg = 'Input has different freq(=.+)? from PeriodIndex\\(freq=M\\)' - with tm.assert_raises_regex(period.IncompatibleFrequency, msg): - rng + o - - # Tick - offsets = [pd.offsets.Day(3), timedelta(days=3), - np.timedelta64(3, 'D'), pd.offsets.Hour(72), - timedelta(minutes=60 * 24 * 3), np.timedelta64(72, 'h'), - Timedelta('72:00:00')] - for delta in offsets: - rng = pd.period_range('2014-05-01', '2014-05-15', freq='D') - result = rng + delta - expected = pd.period_range('2014-05-04', '2014-05-18', freq='D') - tm.assert_index_equal(result, expected) - rng += delta - tm.assert_index_equal(rng, expected) - - for o in [pd.offsets.YearBegin(2), pd.offsets.MonthBegin(1), - pd.offsets.Minute(), np.timedelta64(4, 'h'), - timedelta(hours=23), Timedelta('23:00:00')]: - rng = pd.period_range('2014-05-01', '2014-05-15', freq='D') - msg = 'Input has different freq(=.+)? from PeriodIndex\\(freq=D\\)' - with tm.assert_raises_regex(period.IncompatibleFrequency, msg): - rng + o - - offsets = [pd.offsets.Hour(2), timedelta(hours=2), - np.timedelta64(2, 'h'), pd.offsets.Minute(120), - timedelta(minutes=120), np.timedelta64(120, 'm'), - Timedelta(minutes=120)] - for delta in offsets: - rng = pd.period_range('2014-01-01 10:00', '2014-01-05 10:00', - freq='H') - result = rng + delta - expected = pd.period_range('2014-01-01 12:00', '2014-01-05 12:00', - freq='H') - tm.assert_index_equal(result, expected) - rng += delta - tm.assert_index_equal(rng, expected) - - for delta in [pd.offsets.YearBegin(2), timedelta(minutes=30), - np.timedelta64(30, 's'), Timedelta(seconds=30)]: - rng = pd.period_range('2014-01-01 10:00', '2014-01-05 10:00', - freq='H') - msg = 'Input has different freq(=.+)? from PeriodIndex\\(freq=H\\)' - with tm.assert_raises_regex(period.IncompatibleFrequency, msg): - rng + delta - with tm.assert_raises_regex(period.IncompatibleFrequency, msg): - rng += delta - - def test_pi_add_int(self, one): + def test_pi_add_iadd_int(self, one): # Variants of `one` for #19012 rng = pd.period_range('2000-01-01 09:00', freq='H', periods=10) result = rng + one @@ -301,8 +233,17 @@ def test_pi_add_int(self, one): rng += one tm.assert_index_equal(rng, expected) + def test_pi_sub_isub_int(self, one): + # int + rng = pd.period_range('2000-01-01 09:00', freq='H', periods=10) + result = rng - one + expected = pd.period_range('2000-01-01 08:00', freq='H', periods=10) + tm.assert_index_equal(result, expected) + rng -= one + tm.assert_index_equal(rng, expected) + @pytest.mark.parametrize('five', [5, np.array(5, dtype=np.int64)]) - def test_sub(self, five): + def test_pi_sub_intlike(self, five): rng = period_range('2007-01', periods=50) result = rng - five @@ -321,7 +262,7 @@ def test_pi_sub_isub_pi_raises(self): with pytest.raises(TypeError): rng -= other - def test_sub_isub(self): + def test_pi_sub_isub_offset(self): # offset # DateOffset rng = pd.period_range('2014', '2024', freq='A') @@ -331,82 +272,214 @@ def test_sub_isub(self): rng -= pd.offsets.YearEnd(5) tm.assert_index_equal(rng, expected) - for o in [pd.offsets.YearBegin(2), pd.offsets.MonthBegin(1), - pd.offsets.Minute(), np.timedelta64(365, 'D'), - timedelta(365)]: - rng = pd.period_range('2014', '2024', freq='A') - msg = ('Input has different freq(=.+)? ' - 'from PeriodIndex\\(freq=A-DEC\\)') - with tm.assert_raises_regex( - period.IncompatibleFrequency, msg): - rng - o - rng = pd.period_range('2014-01', '2016-12', freq='M') result = rng - pd.offsets.MonthEnd(5) expected = pd.period_range('2013-08', '2016-07', freq='M') tm.assert_index_equal(result, expected) + rng -= pd.offsets.MonthEnd(5) tm.assert_index_equal(rng, expected) - for o in [pd.offsets.YearBegin(2), pd.offsets.MonthBegin(1), - pd.offsets.Minute(), np.timedelta64(365, 'D'), - timedelta(365)]: - rng = pd.period_range('2014-01', '2016-12', freq='M') - msg = 'Input has different freq(=.+)? from PeriodIndex\\(freq=M\\)' - with tm.assert_raises_regex(period.IncompatibleFrequency, msg): - rng - o - + # --------------------------------------------------------------- + # Timedelta-like (timedelta, timedelta64, Timedelta, Tick) + # TODO: Some of these are misnomers because of non-Tick DateOffsets + + @pytest.mark.parametrize('other', [ + pd.offsets.Day(3), + timedelta(days=3), + np.timedelta64(3, 'D'), + pd.offsets.Hour(72), + timedelta(minutes=60 * 24 * 3), + np.timedelta64(72, 'h'), + Timedelta('72:00:00')]) + def test_pi_add_iadd_timedeltalike_daily(self, other): # Tick - offsets = [pd.offsets.Day(3), timedelta(days=3), - np.timedelta64(3, 'D'), pd.offsets.Hour(72), - timedelta(minutes=60 * 24 * 3), np.timedelta64(72, 'h')] - for delta in offsets: - rng = pd.period_range('2014-05-01', '2014-05-15', freq='D') - result = rng - delta - expected = pd.period_range('2014-04-28', '2014-05-12', freq='D') - tm.assert_index_equal(result, expected) - rng -= delta - tm.assert_index_equal(rng, expected) - - for o in [pd.offsets.YearBegin(2), pd.offsets.MonthBegin(1), - pd.offsets.Minute(), np.timedelta64(4, 'h'), - timedelta(hours=23)]: - rng = pd.period_range('2014-05-01', '2014-05-15', freq='D') - msg = 'Input has different freq(=.+)? from PeriodIndex\\(freq=D\\)' - with tm.assert_raises_regex(period.IncompatibleFrequency, msg): - rng - o - - offsets = [pd.offsets.Hour(2), timedelta(hours=2), - np.timedelta64(2, 'h'), pd.offsets.Minute(120), - timedelta(minutes=120), np.timedelta64(120, 'm')] - for delta in offsets: - rng = pd.period_range('2014-01-01 10:00', '2014-01-05 10:00', - freq='H') - result = rng - delta - expected = pd.period_range('2014-01-01 08:00', '2014-01-05 08:00', - freq='H') - tm.assert_index_equal(result, expected) - rng -= delta - tm.assert_index_equal(rng, expected) - - for delta in [pd.offsets.YearBegin(2), timedelta(minutes=30), - np.timedelta64(30, 's')]: - rng = pd.period_range('2014-01-01 10:00', '2014-01-05 10:00', - freq='H') - msg = 'Input has different freq(=.+)? from PeriodIndex\\(freq=H\\)' - with tm.assert_raises_regex(period.IncompatibleFrequency, msg): - rng + delta - with tm.assert_raises_regex(period.IncompatibleFrequency, msg): - rng += delta + rng = pd.period_range('2014-05-01', '2014-05-15', freq='D') + expected = pd.period_range('2014-05-04', '2014-05-18', freq='D') - # int - rng = pd.period_range('2000-01-01 09:00', freq='H', periods=10) - result = rng - 1 - expected = pd.period_range('2000-01-01 08:00', freq='H', periods=10) + result = rng + other + tm.assert_index_equal(result, expected) + + rng += other + tm.assert_index_equal(rng, expected) + + @pytest.mark.parametrize('other', [ + pd.offsets.Day(3), + timedelta(days=3), + np.timedelta64(3, 'D'), + pd.offsets.Hour(72), + timedelta(minutes=60 * 24 * 3), + np.timedelta64(72, 'h')]) + def test_pi_sub_isub_timedeltalike_daily(self, other): + # Tick-like 3 Days + rng = pd.period_range('2014-05-01', '2014-05-15', freq='D') + expected = pd.period_range('2014-04-28', '2014-05-12', freq='D') + + result = rng - other + tm.assert_index_equal(result, expected) + + rng -= other + tm.assert_index_equal(rng, expected) + + @pytest.mark.parametrize('other', [ + pd.offsets.YearBegin(2), + pd.offsets.MonthBegin(1), + pd.offsets.Minute(), + np.timedelta64(4, 'h'), + timedelta(hours=23), + Timedelta('23:00:00')]) + def test_pi_add_iadd_timedeltalike_freq_mismatch_daily(self, other): + rng = pd.period_range('2014-05-01', '2014-05-15', freq='D') + msg = 'Input has different freq(=.+)? from PeriodIndex\\(freq=D\\)' + with tm.assert_raises_regex(period.IncompatibleFrequency, msg): + rng + other + with tm.assert_raises_regex(period.IncompatibleFrequency, msg): + rng += other + + @pytest.mark.parametrize('other', [ + pd.offsets.YearBegin(2), + pd.offsets.MonthBegin(1), + pd.offsets.Minute(), + np.timedelta64(4, 'h'), + timedelta(hours=23)]) + def test_pi_sub_timedeltalike_freq_mismatch_daily(self, other): + rng = pd.period_range('2014-05-01', '2014-05-15', freq='D') + msg = 'Input has different freq(=.+)? from PeriodIndex\\(freq=D\\)' + with tm.assert_raises_regex(period.IncompatibleFrequency, msg): + rng - other + + @pytest.mark.parametrize('other', [ + pd.offsets.Hour(2), + timedelta(hours=2), + np.timedelta64(2, 'h'), + pd.offsets.Minute(120), + timedelta(minutes=120), + np.timedelta64(120, 'm'), + Timedelta(minutes=120)]) + def test_pi_add_iadd_timedeltalike_hourly(self, other): + rng = pd.period_range('2014-01-01 10:00', '2014-01-05 10:00', freq='H') + expected = pd.period_range('2014-01-01 12:00', '2014-01-05 12:00', + freq='H') + + result = rng + other + tm.assert_index_equal(result, expected) + + rng += other + tm.assert_index_equal(rng, expected) + + @pytest.mark.parametrize('other', [ + pd.offsets.YearBegin(2), + timedelta(minutes=30), + np.timedelta64(30, 's'), + Timedelta(seconds=30)]) + def test_pi_add_timedeltalike_mismatched_freq_hourly(self, other): + rng = pd.period_range('2014-01-01 10:00', '2014-01-05 10:00', freq='H') + msg = 'Input has different freq(=.+)? from PeriodIndex\\(freq=H\\)' + + with tm.assert_raises_regex(period.IncompatibleFrequency, msg): + rng + other + + with tm.assert_raises_regex(period.IncompatibleFrequency, msg): + rng += other + + @pytest.mark.parametrize('other', [ + pd.offsets.Hour(2), + timedelta(hours=2), + np.timedelta64(2, 'h'), + pd.offsets.Minute(120), + timedelta(minutes=120), + np.timedelta64(120, 'm')]) + def test_pi_sub_isub_timedeltalike_hourly(self, other): + rng = pd.period_range('2014-01-01 10:00', '2014-01-05 10:00', freq='H') + expected = pd.period_range('2014-01-01 08:00', '2014-01-05 08:00', + freq='H') + + result = rng - other + tm.assert_index_equal(result, expected) + + rng -= other + tm.assert_index_equal(rng, expected) + + def test_add_iadd_timedeltalike_annual(self): + # offset + # DateOffset + rng = pd.period_range('2014', '2024', freq='A') + result = rng + pd.offsets.YearEnd(5) + expected = pd.period_range('2019', '2029', freq='A') + tm.assert_index_equal(result, expected) + rng += pd.offsets.YearEnd(5) + tm.assert_index_equal(rng, expected) + + @pytest.mark.parametrize('other', [ + pd.offsets.YearBegin(2), + pd.offsets.MonthBegin(1), + pd.offsets.Minute(), + np.timedelta64(365, 'D'), + timedelta(365), + Timedelta(days=365)]) + def test_pi_add_iadd_timedeltalike_freq_mismatch_annual(self, other): + rng = pd.period_range('2014', '2024', freq='A') + msg = ('Input has different freq(=.+)? ' + 'from PeriodIndex\\(freq=A-DEC\\)') + with tm.assert_raises_regex(period.IncompatibleFrequency, msg): + rng + other + with tm.assert_raises_regex(period.IncompatibleFrequency, msg): + rng += other + + @pytest.mark.parametrize('other', [ + pd.offsets.YearBegin(2), + pd.offsets.MonthBegin(1), + pd.offsets.Minute(), + np.timedelta64(365, 'D'), + timedelta(365)]) + def test_pi_sub_isub_timedeltalike_freq_mismatch_annual(self, other): + rng = pd.period_range('2014', '2024', freq='A') + msg = ('Input has different freq(=.+)? ' + 'from PeriodIndex\\(freq=A-DEC\\)') + with tm.assert_raises_regex(period.IncompatibleFrequency, msg): + rng - other + with tm.assert_raises_regex(period.IncompatibleFrequency, msg): + rng -= other + + def test_pi_add_iadd_timedeltalike_monthly(self): + rng = pd.period_range('2014-01', '2016-12', freq='M') + expected = pd.period_range('2014-06', '2017-05', freq='M') + + result = rng + pd.offsets.MonthEnd(5) tm.assert_index_equal(result, expected) - rng -= 1 + + rng += pd.offsets.MonthEnd(5) tm.assert_index_equal(rng, expected) + @pytest.mark.parametrize('other', [ + pd.offsets.YearBegin(2), + pd.offsets.MonthBegin(1), + pd.offsets.Minute(), + np.timedelta64(365, 'D'), + timedelta(365), + Timedelta(days=365)]) + def test_pi_add_iadd_timedeltalike_freq_mismatch_monthly(self, other): + rng = pd.period_range('2014-01', '2016-12', freq='M') + msg = 'Input has different freq(=.+)? from PeriodIndex\\(freq=M\\)' + with tm.assert_raises_regex(period.IncompatibleFrequency, msg): + rng + other + with tm.assert_raises_regex(period.IncompatibleFrequency, msg): + rng += other + + @pytest.mark.parametrize('other', [ + pd.offsets.YearBegin(2), + pd.offsets.MonthBegin(1), + pd.offsets.Minute(), + np.timedelta64(365, 'D'), + timedelta(365)]) + def test_pi_sub_isub_timedeltalike_freq_mismatch_monthly(self, other): + rng = pd.period_range('2014-01', '2016-12', freq='M') + msg = 'Input has different freq(=.+)? from PeriodIndex\\(freq=M\\)' + with tm.assert_raises_regex(period.IncompatibleFrequency, msg): + rng - other + with tm.assert_raises_regex(period.IncompatibleFrequency, msg): + rng -= other + # --------------------------------------------------------------- # PeriodIndex.shift is used by __add__ and __sub__ @@ -418,8 +491,6 @@ def test_pi_shift_ndarray(self): freq='M', name='idx') tm.assert_index_equal(result, expected) - idx = PeriodIndex(['2011-01', '2011-02', 'NaT', '2011-04'], - freq='M', name='idx') result = idx.shift(np.array([1, -2, 3, -4])) expected = PeriodIndex(['2011-02', '2010-12', 'NaT', '2010-12'], freq='M', name='idx') diff --git a/pandas/tests/indexes/period/test_astype.py b/pandas/tests/indexes/period/test_astype.py new file mode 100644 index 0000000000000..f2126487496c4 --- /dev/null +++ b/pandas/tests/indexes/period/test_astype.py @@ -0,0 +1,99 @@ +# -*- coding: utf-8 -*- + +import numpy as np +import pytest + +import pandas as pd +import pandas.util.testing as tm +from pandas import NaT, Period, PeriodIndex, Int64Index, Index, period_range + + +class TestPeriodIndexAsType(object): + @pytest.mark.parametrize('dtype', [ + float, 'timedelta64', 'timedelta64[ns]']) + def test_astype_raises(self, dtype): + # GH#13149, GH#13209 + idx = PeriodIndex(['2016-05-16', 'NaT', NaT, np.NaN], freq='D') + msg = 'Cannot cast PeriodIndex to dtype' + with tm.assert_raises_regex(TypeError, msg): + idx.astype(dtype) + + def test_astype_conversion(self): + # GH#13149, GH#13209 + idx = PeriodIndex(['2016-05-16', 'NaT', NaT, np.NaN], freq='D') + + result = idx.astype(object) + expected = Index([Period('2016-05-16', freq='D')] + + [Period(NaT, freq='D')] * 3, dtype='object') + tm.assert_index_equal(result, expected) + + result = idx.astype(int) + expected = Int64Index([16937] + [-9223372036854775808] * 3, + dtype=np.int64) + tm.assert_index_equal(result, expected) + + result = idx.astype(str) + expected = Index(str(x) for x in idx) + tm.assert_index_equal(result, expected) + + idx = period_range('1990', '2009', freq='A') + result = idx.astype('i8') + tm.assert_index_equal(result, Index(idx.asi8)) + tm.assert_numpy_array_equal(result.values, idx.asi8) + + def test_astype_object(self): + idx = pd.PeriodIndex([], freq='M') + + exp = np.array([], dtype=object) + tm.assert_numpy_array_equal(idx.astype(object).values, exp) + tm.assert_numpy_array_equal(idx._mpl_repr(), exp) + + idx = pd.PeriodIndex(['2011-01', pd.NaT], freq='M') + + exp = np.array([pd.Period('2011-01', freq='M'), pd.NaT], dtype=object) + tm.assert_numpy_array_equal(idx.astype(object).values, exp) + tm.assert_numpy_array_equal(idx._mpl_repr(), exp) + + exp = np.array([pd.Period('2011-01-01', freq='D'), pd.NaT], + dtype=object) + idx = pd.PeriodIndex(['2011-01-01', pd.NaT], freq='D') + tm.assert_numpy_array_equal(idx.astype(object).values, exp) + tm.assert_numpy_array_equal(idx._mpl_repr(), exp) + + # TODO: de-duplicate this version (from test_ops) with the one above + # (from test_period) + def test_astype_object2(self): + idx = pd.period_range(start='2013-01-01', periods=4, freq='M', + name='idx') + expected_list = [pd.Period('2013-01-31', freq='M'), + pd.Period('2013-02-28', freq='M'), + pd.Period('2013-03-31', freq='M'), + pd.Period('2013-04-30', freq='M')] + expected = pd.Index(expected_list, dtype=object, name='idx') + result = idx.astype(object) + assert isinstance(result, Index) + assert result.dtype == object + tm.assert_index_equal(result, expected) + assert result.name == expected.name + assert idx.tolist() == expected_list + + idx = PeriodIndex(['2013-01-01', '2013-01-02', 'NaT', + '2013-01-04'], freq='D', name='idx') + expected_list = [pd.Period('2013-01-01', freq='D'), + pd.Period('2013-01-02', freq='D'), + pd.Period('NaT', freq='D'), + pd.Period('2013-01-04', freq='D')] + expected = pd.Index(expected_list, dtype=object, name='idx') + result = idx.astype(object) + assert isinstance(result, Index) + assert result.dtype == object + tm.assert_index_equal(result, expected) + for i in [0, 1, 3]: + assert result[i] == expected[i] + assert result[2] is pd.NaT + assert result.name == expected.name + + result_list = idx.tolist() + for i in [0, 1, 3]: + assert result_list[i] == expected_list[i] + assert result_list[2] is pd.NaT diff --git a/pandas/tests/indexes/period/test_ops.py b/pandas/tests/indexes/period/test_ops.py index 8745de0c2a7aa..6c272864e0026 100644 --- a/pandas/tests/indexes/period/test_ops.py +++ b/pandas/tests/indexes/period/test_ops.py @@ -25,42 +25,6 @@ def test_ops_properties(self): self.check_ops_properties(PeriodIndex._object_ops, f) self.check_ops_properties(PeriodIndex._bool_ops, f) - def test_astype_object(self): - idx = pd.period_range(start='2013-01-01', periods=4, freq='M', - name='idx') - expected_list = [pd.Period('2013-01-31', freq='M'), - pd.Period('2013-02-28', freq='M'), - pd.Period('2013-03-31', freq='M'), - pd.Period('2013-04-30', freq='M')] - expected = pd.Index(expected_list, dtype=object, name='idx') - result = idx.astype(object) - assert isinstance(result, Index) - assert result.dtype == object - tm.assert_index_equal(result, expected) - assert result.name == expected.name - assert idx.tolist() == expected_list - - idx = PeriodIndex(['2013-01-01', '2013-01-02', 'NaT', - '2013-01-04'], freq='D', name='idx') - expected_list = [pd.Period('2013-01-01', freq='D'), - pd.Period('2013-01-02', freq='D'), - pd.Period('NaT', freq='D'), - pd.Period('2013-01-04', freq='D')] - expected = pd.Index(expected_list, dtype=object, name='idx') - result = idx.astype(object) - assert isinstance(result, Index) - assert result.dtype == object - tm.assert_index_equal(result, expected) - for i in [0, 1, 3]: - assert result[i] == expected[i] - assert result[2] is pd.NaT - assert result.name == expected.name - - result_list = idx.tolist() - for i in [0, 1, 3]: - assert result_list[i] == expected_list[i] - assert result_list[2] is pd.NaT - def test_minmax(self): # monotonic diff --git a/pandas/tests/indexes/period/test_period.py b/pandas/tests/indexes/period/test_period.py index f3469b829f8a3..b1fa9e27fd5b2 100644 --- a/pandas/tests/indexes/period/test_period.py +++ b/pandas/tests/indexes/period/test_period.py @@ -6,7 +6,7 @@ import pandas.util._test_decorators as td from pandas.util import testing as tm from pandas import (PeriodIndex, period_range, notna, DatetimeIndex, NaT, - Index, Period, Int64Index, Series, DataFrame, date_range, + Index, Period, Series, DataFrame, date_range, offsets) from ..datetimelike import DatetimeLike @@ -24,38 +24,6 @@ def setup_method(self, method): def create_index(self): return period_range('20130101', periods=5, freq='D') - def test_astype_conversion(self): - # GH 13149, GH 13209 - idx = PeriodIndex(['2016-05-16', 'NaT', NaT, np.NaN], freq='D') - - result = idx.astype(object) - expected = Index([Period('2016-05-16', freq='D')] + - [Period(NaT, freq='D')] * 3, dtype='object') - tm.assert_index_equal(result, expected) - - result = idx.astype(int) - expected = Int64Index([16937] + [-9223372036854775808] * 3, - dtype=np.int64) - tm.assert_index_equal(result, expected) - - result = idx.astype(str) - expected = Index(str(x) for x in idx) - tm.assert_index_equal(result, expected) - - idx = period_range('1990', '2009', freq='A') - result = idx.astype('i8') - tm.assert_index_equal(result, Index(idx.asi8)) - tm.assert_numpy_array_equal(result.values, idx.asi8) - - @pytest.mark.parametrize('dtype', [ - float, 'timedelta64', 'timedelta64[ns]']) - def test_astype_raises(self, dtype): - # GH 13149, GH 13209 - idx = PeriodIndex(['2016-05-16', 'NaT', NaT, np.NaN], freq='D') - msg = 'Cannot cast PeriodIndex to dtype' - with tm.assert_raises_regex(TypeError, msg): - idx.astype(dtype) - def test_pickle_compat_construction(self): pass @@ -384,25 +352,6 @@ def test_factorize(self): tm.assert_numpy_array_equal(arr, exp_arr) tm.assert_index_equal(idx, exp_idx) - def test_astype_object(self): - idx = pd.PeriodIndex([], freq='M') - - exp = np.array([], dtype=object) - tm.assert_numpy_array_equal(idx.astype(object).values, exp) - tm.assert_numpy_array_equal(idx._mpl_repr(), exp) - - idx = pd.PeriodIndex(['2011-01', pd.NaT], freq='M') - - exp = np.array([pd.Period('2011-01', freq='M'), pd.NaT], dtype=object) - tm.assert_numpy_array_equal(idx.astype(object).values, exp) - tm.assert_numpy_array_equal(idx._mpl_repr(), exp) - - exp = np.array([pd.Period('2011-01-01', freq='D'), pd.NaT], - dtype=object) - idx = pd.PeriodIndex(['2011-01-01', pd.NaT], freq='D') - tm.assert_numpy_array_equal(idx.astype(object).values, exp) - tm.assert_numpy_array_equal(idx._mpl_repr(), exp) - def test_is_(self): create_index = lambda: PeriodIndex(freq='A', start='1/1/2001', end='12/1/2009') @@ -421,13 +370,6 @@ def test_is_(self): assert not index.is_(index - 2) assert not index.is_(index - 0) - def test_comp_period(self): - idx = period_range('2007-01', periods=20, freq='M') - - result = idx < idx[10] - exp = idx.values < idx.values[10] - tm.assert_numpy_array_equal(result, exp) - def test_contains(self): rng = period_range('2007-01', freq='M', periods=10) From 8cf154a8e85dd167e4fdb4719698152ddb15fa5e Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Mon, 12 Feb 2018 16:03:10 -0800 Subject: [PATCH 3/7] fixup typo --- pandas/tests/indexes/period/test_arithmetic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/indexes/period/test_arithmetic.py b/pandas/tests/indexes/period/test_arithmetic.py index b97f2051e930e..8b02de74d2c35 100644 --- a/pandas/tests/indexes/period/test_arithmetic.py +++ b/pandas/tests/indexes/period/test_arithmetic.py @@ -163,7 +163,7 @@ def test_comp_nat(self, dtype): if dtype is not None: left = left.astype(dtype) - right = right.dtype + right = right.astype(dtype) result = left == right expected = np.array([False, False, True]) From 7fc7c0f134a983d6ca3314533c99c43ba90c6651 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Wed, 14 Feb 2018 09:37:46 -0800 Subject: [PATCH 4/7] put lists of params at module level --- .../tests/indexes/period/test_arithmetic.py | 117 +++++++----------- 1 file changed, 43 insertions(+), 74 deletions(-) diff --git a/pandas/tests/indexes/period/test_arithmetic.py b/pandas/tests/indexes/period/test_arithmetic.py index 8b02de74d2c35..56d460885d1b9 100644 --- a/pandas/tests/indexes/period/test_arithmetic.py +++ b/pandas/tests/indexes/period/test_arithmetic.py @@ -11,6 +11,38 @@ import pandas.core.indexes.period as period +_common_mismatch = [pd.offsets.YearBegin(2), + pd.offsets.MonthBegin(1), + pd.offsets.Minute()] + +not_hourly_offsets = [timedelta(minutes=30), + np.timedelta64(30, 's'), + Timedelta(seconds=30)] + _common_mismatch + +not_daily_offsets = [np.timedelta64(4, 'h'), + timedelta(hours=23), + Timedelta('23:00:00')] + _common_mismatch + +mismatched_offsets = [np.timedelta64(365, 'D'), + timedelta(365), + Timedelta(days=365)] + _common_mismatch + +three_days = [pd.offsets.Day(3), + timedelta(days=3), + np.timedelta64(3, 'D'), + pd.offsets.Hour(72), + timedelta(minutes=60 * 24 * 3), + np.timedelta64(72, 'h'), + Timedelta('72:00:00')] + +two_hours = [pd.offsets.Hour(2), + timedelta(hours=2), + np.timedelta64(2, 'h'), + pd.offsets.Minute(120), + timedelta(minutes=120), + np.timedelta64(120, 'm')] + + class TestPeriodIndexComparisons(object): def test_pi_cmp_period(self): idx = period_range('2007-01', periods=20, freq='M') @@ -284,14 +316,7 @@ def test_pi_sub_isub_offset(self): # Timedelta-like (timedelta, timedelta64, Timedelta, Tick) # TODO: Some of these are misnomers because of non-Tick DateOffsets - @pytest.mark.parametrize('other', [ - pd.offsets.Day(3), - timedelta(days=3), - np.timedelta64(3, 'D'), - pd.offsets.Hour(72), - timedelta(minutes=60 * 24 * 3), - np.timedelta64(72, 'h'), - Timedelta('72:00:00')]) + @pytest.mark.parametrize('other', three_days) def test_pi_add_iadd_timedeltalike_daily(self, other): # Tick rng = pd.period_range('2014-05-01', '2014-05-15', freq='D') @@ -303,13 +328,7 @@ def test_pi_add_iadd_timedeltalike_daily(self, other): rng += other tm.assert_index_equal(rng, expected) - @pytest.mark.parametrize('other', [ - pd.offsets.Day(3), - timedelta(days=3), - np.timedelta64(3, 'D'), - pd.offsets.Hour(72), - timedelta(minutes=60 * 24 * 3), - np.timedelta64(72, 'h')]) + @pytest.mark.parametrize('other', three_days) def test_pi_sub_isub_timedeltalike_daily(self, other): # Tick-like 3 Days rng = pd.period_range('2014-05-01', '2014-05-15', freq='D') @@ -321,13 +340,7 @@ def test_pi_sub_isub_timedeltalike_daily(self, other): rng -= other tm.assert_index_equal(rng, expected) - @pytest.mark.parametrize('other', [ - pd.offsets.YearBegin(2), - pd.offsets.MonthBegin(1), - pd.offsets.Minute(), - np.timedelta64(4, 'h'), - timedelta(hours=23), - Timedelta('23:00:00')]) + @pytest.mark.parametrize('other', not_daily_offsets) def test_pi_add_iadd_timedeltalike_freq_mismatch_daily(self, other): rng = pd.period_range('2014-05-01', '2014-05-15', freq='D') msg = 'Input has different freq(=.+)? from PeriodIndex\\(freq=D\\)' @@ -336,26 +349,14 @@ def test_pi_add_iadd_timedeltalike_freq_mismatch_daily(self, other): with tm.assert_raises_regex(period.IncompatibleFrequency, msg): rng += other - @pytest.mark.parametrize('other', [ - pd.offsets.YearBegin(2), - pd.offsets.MonthBegin(1), - pd.offsets.Minute(), - np.timedelta64(4, 'h'), - timedelta(hours=23)]) + @pytest.mark.parametrize('other', not_daily_offsets) def test_pi_sub_timedeltalike_freq_mismatch_daily(self, other): rng = pd.period_range('2014-05-01', '2014-05-15', freq='D') msg = 'Input has different freq(=.+)? from PeriodIndex\\(freq=D\\)' with tm.assert_raises_regex(period.IncompatibleFrequency, msg): rng - other - @pytest.mark.parametrize('other', [ - pd.offsets.Hour(2), - timedelta(hours=2), - np.timedelta64(2, 'h'), - pd.offsets.Minute(120), - timedelta(minutes=120), - np.timedelta64(120, 'm'), - Timedelta(minutes=120)]) + @pytest.mark.parametrize('other', two_hours) def test_pi_add_iadd_timedeltalike_hourly(self, other): rng = pd.period_range('2014-01-01 10:00', '2014-01-05 10:00', freq='H') expected = pd.period_range('2014-01-01 12:00', '2014-01-05 12:00', @@ -367,11 +368,7 @@ def test_pi_add_iadd_timedeltalike_hourly(self, other): rng += other tm.assert_index_equal(rng, expected) - @pytest.mark.parametrize('other', [ - pd.offsets.YearBegin(2), - timedelta(minutes=30), - np.timedelta64(30, 's'), - Timedelta(seconds=30)]) + @pytest.mark.parametrize('other', not_hourly_offsets) def test_pi_add_timedeltalike_mismatched_freq_hourly(self, other): rng = pd.period_range('2014-01-01 10:00', '2014-01-05 10:00', freq='H') msg = 'Input has different freq(=.+)? from PeriodIndex\\(freq=H\\)' @@ -382,13 +379,7 @@ def test_pi_add_timedeltalike_mismatched_freq_hourly(self, other): with tm.assert_raises_regex(period.IncompatibleFrequency, msg): rng += other - @pytest.mark.parametrize('other', [ - pd.offsets.Hour(2), - timedelta(hours=2), - np.timedelta64(2, 'h'), - pd.offsets.Minute(120), - timedelta(minutes=120), - np.timedelta64(120, 'm')]) + @pytest.mark.parametrize('other', two_hours) def test_pi_sub_isub_timedeltalike_hourly(self, other): rng = pd.period_range('2014-01-01 10:00', '2014-01-05 10:00', freq='H') expected = pd.period_range('2014-01-01 08:00', '2014-01-05 08:00', @@ -410,13 +401,7 @@ def test_add_iadd_timedeltalike_annual(self): rng += pd.offsets.YearEnd(5) tm.assert_index_equal(rng, expected) - @pytest.mark.parametrize('other', [ - pd.offsets.YearBegin(2), - pd.offsets.MonthBegin(1), - pd.offsets.Minute(), - np.timedelta64(365, 'D'), - timedelta(365), - Timedelta(days=365)]) + @pytest.mark.parametrize('other', mismatched_offsets) def test_pi_add_iadd_timedeltalike_freq_mismatch_annual(self, other): rng = pd.period_range('2014', '2024', freq='A') msg = ('Input has different freq(=.+)? ' @@ -426,12 +411,7 @@ def test_pi_add_iadd_timedeltalike_freq_mismatch_annual(self, other): with tm.assert_raises_regex(period.IncompatibleFrequency, msg): rng += other - @pytest.mark.parametrize('other', [ - pd.offsets.YearBegin(2), - pd.offsets.MonthBegin(1), - pd.offsets.Minute(), - np.timedelta64(365, 'D'), - timedelta(365)]) + @pytest.mark.parametrize('other', mismatched_offsets) def test_pi_sub_isub_timedeltalike_freq_mismatch_annual(self, other): rng = pd.period_range('2014', '2024', freq='A') msg = ('Input has different freq(=.+)? ' @@ -451,13 +431,7 @@ def test_pi_add_iadd_timedeltalike_monthly(self): rng += pd.offsets.MonthEnd(5) tm.assert_index_equal(rng, expected) - @pytest.mark.parametrize('other', [ - pd.offsets.YearBegin(2), - pd.offsets.MonthBegin(1), - pd.offsets.Minute(), - np.timedelta64(365, 'D'), - timedelta(365), - Timedelta(days=365)]) + @pytest.mark.parametrize('other', mismatched_offsets) def test_pi_add_iadd_timedeltalike_freq_mismatch_monthly(self, other): rng = pd.period_range('2014-01', '2016-12', freq='M') msg = 'Input has different freq(=.+)? from PeriodIndex\\(freq=M\\)' @@ -466,12 +440,7 @@ def test_pi_add_iadd_timedeltalike_freq_mismatch_monthly(self, other): with tm.assert_raises_regex(period.IncompatibleFrequency, msg): rng += other - @pytest.mark.parametrize('other', [ - pd.offsets.YearBegin(2), - pd.offsets.MonthBegin(1), - pd.offsets.Minute(), - np.timedelta64(365, 'D'), - timedelta(365)]) + @pytest.mark.parametrize('other', mismatched_offsets) def test_pi_sub_isub_timedeltalike_freq_mismatch_monthly(self, other): rng = pd.period_range('2014-01', '2016-12', freq='M') msg = 'Input has different freq(=.+)? from PeriodIndex\\(freq=M\\)' From fa63ed1fc551132f4d629169476934fa28e8949f Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Thu, 15 Feb 2018 07:49:42 -0800 Subject: [PATCH 5/7] make fixtures --- .../tests/indexes/period/test_arithmetic.py | 115 ++++++++++-------- 1 file changed, 66 insertions(+), 49 deletions(-) diff --git a/pandas/tests/indexes/period/test_arithmetic.py b/pandas/tests/indexes/period/test_arithmetic.py index 56d460885d1b9..dd770d18a894f 100644 --- a/pandas/tests/indexes/period/test_arithmetic.py +++ b/pandas/tests/indexes/period/test_arithmetic.py @@ -15,32 +15,49 @@ pd.offsets.MonthBegin(1), pd.offsets.Minute()] -not_hourly_offsets = [timedelta(minutes=30), - np.timedelta64(30, 's'), - Timedelta(seconds=30)] + _common_mismatch - -not_daily_offsets = [np.timedelta64(4, 'h'), - timedelta(hours=23), - Timedelta('23:00:00')] + _common_mismatch - -mismatched_offsets = [np.timedelta64(365, 'D'), - timedelta(365), - Timedelta(days=365)] + _common_mismatch - -three_days = [pd.offsets.Day(3), - timedelta(days=3), - np.timedelta64(3, 'D'), - pd.offsets.Hour(72), - timedelta(minutes=60 * 24 * 3), - np.timedelta64(72, 'h'), - Timedelta('72:00:00')] - -two_hours = [pd.offsets.Hour(2), - timedelta(hours=2), - np.timedelta64(2, 'h'), - pd.offsets.Minute(120), - timedelta(minutes=120), - np.timedelta64(120, 'm')] + +@pytest.fixture(params=[timedelta(minutes=30), + np.timedelta64(30, 's'), + Timedelta(seconds=30)] + _common_mismatch) +def not_hourly(request): + return request.param + + +@pytest.fixture(params=[np.timedelta64(4, 'h'), + timedelta(hours=23), + Timedelta('23:00:00')] + _common_mismatch) +def not_daily(request): + return request.param + + +@pytest.fixture(params=[np.timedelta64(365, 'D'), + timedelta(365), + Timedelta(days=365)] + _common_mismatch) +def mismatched(request): + return request.param + + +@pytest.fixture(params=[pd.offsets.Day(3), + timedelta(days=3), + np.timedelta64(3, 'D'), + pd.offsets.Hour(72), + timedelta(minutes=60 * 24 * 3), + np.timedelta64(72, 'h'), + Timedelta('72:00:00')]) +def three_days(request): + # several timedelta/offset-like objects representing a 3-day timedelta + return request.param + + +@pytest.fixture(params=[pd.offsets.Hour(2), + timedelta(hours=2), + np.timedelta64(2, 'h'), + pd.offsets.Minute(120), + timedelta(minutes=120), + np.timedelta64(120, 'm')]) +def two_hours(request): + # several timedelta/offset-like objects representing a 2-hour timedelta + return request.param class TestPeriodIndexComparisons(object): @@ -316,9 +333,9 @@ def test_pi_sub_isub_offset(self): # Timedelta-like (timedelta, timedelta64, Timedelta, Tick) # TODO: Some of these are misnomers because of non-Tick DateOffsets - @pytest.mark.parametrize('other', three_days) - def test_pi_add_iadd_timedeltalike_daily(self, other): + def test_pi_add_iadd_timedeltalike_daily(self, three_days): # Tick + other = three_days rng = pd.period_range('2014-05-01', '2014-05-15', freq='D') expected = pd.period_range('2014-05-04', '2014-05-18', freq='D') @@ -328,9 +345,9 @@ def test_pi_add_iadd_timedeltalike_daily(self, other): rng += other tm.assert_index_equal(rng, expected) - @pytest.mark.parametrize('other', three_days) - def test_pi_sub_isub_timedeltalike_daily(self, other): + def test_pi_sub_isub_timedeltalike_daily(self, three_days): # Tick-like 3 Days + other = three_days rng = pd.period_range('2014-05-01', '2014-05-15', freq='D') expected = pd.period_range('2014-04-28', '2014-05-12', freq='D') @@ -340,8 +357,8 @@ def test_pi_sub_isub_timedeltalike_daily(self, other): rng -= other tm.assert_index_equal(rng, expected) - @pytest.mark.parametrize('other', not_daily_offsets) - def test_pi_add_iadd_timedeltalike_freq_mismatch_daily(self, other): + def test_pi_add_iadd_timedeltalike_freq_mismatch_daily(self, not_daily): + other = not_daily rng = pd.period_range('2014-05-01', '2014-05-15', freq='D') msg = 'Input has different freq(=.+)? from PeriodIndex\\(freq=D\\)' with tm.assert_raises_regex(period.IncompatibleFrequency, msg): @@ -349,15 +366,15 @@ def test_pi_add_iadd_timedeltalike_freq_mismatch_daily(self, other): with tm.assert_raises_regex(period.IncompatibleFrequency, msg): rng += other - @pytest.mark.parametrize('other', not_daily_offsets) - def test_pi_sub_timedeltalike_freq_mismatch_daily(self, other): + def test_pi_sub_timedeltalike_freq_mismatch_daily(self, not_daily): + other = not_daily rng = pd.period_range('2014-05-01', '2014-05-15', freq='D') msg = 'Input has different freq(=.+)? from PeriodIndex\\(freq=D\\)' with tm.assert_raises_regex(period.IncompatibleFrequency, msg): rng - other - @pytest.mark.parametrize('other', two_hours) - def test_pi_add_iadd_timedeltalike_hourly(self, other): + def test_pi_add_iadd_timedeltalike_hourly(self, two_hours): + other = two_hours rng = pd.period_range('2014-01-01 10:00', '2014-01-05 10:00', freq='H') expected = pd.period_range('2014-01-01 12:00', '2014-01-05 12:00', freq='H') @@ -368,8 +385,8 @@ def test_pi_add_iadd_timedeltalike_hourly(self, other): rng += other tm.assert_index_equal(rng, expected) - @pytest.mark.parametrize('other', not_hourly_offsets) - def test_pi_add_timedeltalike_mismatched_freq_hourly(self, other): + def test_pi_add_timedeltalike_mismatched_freq_hourly(self, not_hourly): + other = not_hourly rng = pd.period_range('2014-01-01 10:00', '2014-01-05 10:00', freq='H') msg = 'Input has different freq(=.+)? from PeriodIndex\\(freq=H\\)' @@ -379,8 +396,8 @@ def test_pi_add_timedeltalike_mismatched_freq_hourly(self, other): with tm.assert_raises_regex(period.IncompatibleFrequency, msg): rng += other - @pytest.mark.parametrize('other', two_hours) - def test_pi_sub_isub_timedeltalike_hourly(self, other): + def test_pi_sub_isub_timedeltalike_hourly(self, two_hours): + other = two_hours rng = pd.period_range('2014-01-01 10:00', '2014-01-05 10:00', freq='H') expected = pd.period_range('2014-01-01 08:00', '2014-01-05 08:00', freq='H') @@ -401,8 +418,8 @@ def test_add_iadd_timedeltalike_annual(self): rng += pd.offsets.YearEnd(5) tm.assert_index_equal(rng, expected) - @pytest.mark.parametrize('other', mismatched_offsets) - def test_pi_add_iadd_timedeltalike_freq_mismatch_annual(self, other): + def test_pi_add_iadd_timedeltalike_freq_mismatch_annual(self, mismatched): + other = mismatched rng = pd.period_range('2014', '2024', freq='A') msg = ('Input has different freq(=.+)? ' 'from PeriodIndex\\(freq=A-DEC\\)') @@ -411,8 +428,8 @@ def test_pi_add_iadd_timedeltalike_freq_mismatch_annual(self, other): with tm.assert_raises_regex(period.IncompatibleFrequency, msg): rng += other - @pytest.mark.parametrize('other', mismatched_offsets) - def test_pi_sub_isub_timedeltalike_freq_mismatch_annual(self, other): + def test_pi_sub_isub_timedeltalike_freq_mismatch_annual(self, mismatched): + other = mismatched rng = pd.period_range('2014', '2024', freq='A') msg = ('Input has different freq(=.+)? ' 'from PeriodIndex\\(freq=A-DEC\\)') @@ -421,7 +438,7 @@ def test_pi_sub_isub_timedeltalike_freq_mismatch_annual(self, other): with tm.assert_raises_regex(period.IncompatibleFrequency, msg): rng -= other - def test_pi_add_iadd_timedeltalike_monthly(self): + def test_pi_add_iadd_timedeltalike_M(self): rng = pd.period_range('2014-01', '2016-12', freq='M') expected = pd.period_range('2014-06', '2017-05', freq='M') @@ -431,8 +448,8 @@ def test_pi_add_iadd_timedeltalike_monthly(self): rng += pd.offsets.MonthEnd(5) tm.assert_index_equal(rng, expected) - @pytest.mark.parametrize('other', mismatched_offsets) - def test_pi_add_iadd_timedeltalike_freq_mismatch_monthly(self, other): + def test_pi_add_iadd_timedeltalike_freq_mismatch_monthly(self, mismatched): + other = mismatched rng = pd.period_range('2014-01', '2016-12', freq='M') msg = 'Input has different freq(=.+)? from PeriodIndex\\(freq=M\\)' with tm.assert_raises_regex(period.IncompatibleFrequency, msg): @@ -440,8 +457,8 @@ def test_pi_add_iadd_timedeltalike_freq_mismatch_monthly(self, other): with tm.assert_raises_regex(period.IncompatibleFrequency, msg): rng += other - @pytest.mark.parametrize('other', mismatched_offsets) - def test_pi_sub_isub_timedeltalike_freq_mismatch_monthly(self, other): + def test_pi_sub_isub_timedeltalike_freq_mismatch_monthly(self, mismatched): + other = mismatched rng = pd.period_range('2014-01', '2016-12', freq='M') msg = 'Input has different freq(=.+)? from PeriodIndex\\(freq=M\\)' with tm.assert_raises_regex(period.IncompatibleFrequency, msg): From 428417fb87c6f337c8f4d05e275d8450dac3c63b Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Fri, 16 Feb 2018 08:39:52 -0800 Subject: [PATCH 6/7] docstrings for fixtures --- .../tests/indexes/period/test_arithmetic.py | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/pandas/tests/indexes/period/test_arithmetic.py b/pandas/tests/indexes/period/test_arithmetic.py index dd770d18a894f..544bc9a96b999 100644 --- a/pandas/tests/indexes/period/test_arithmetic.py +++ b/pandas/tests/indexes/period/test_arithmetic.py @@ -20,6 +20,10 @@ np.timedelta64(30, 's'), Timedelta(seconds=30)] + _common_mismatch) def not_hourly(request): + """ + Several timedelta-like and DateOffset instances that are _not_ + compatible with Hourly frequencies. + """ return request.param @@ -27,6 +31,10 @@ def not_hourly(request): timedelta(hours=23), Timedelta('23:00:00')] + _common_mismatch) def not_daily(request): + """ + Several timedelta-like and DateOffset instances that are _not_ + compatible with Daily frequencies. + """ return request.param @@ -34,6 +42,10 @@ def not_daily(request): timedelta(365), Timedelta(days=365)] + _common_mismatch) def mismatched(request): + """ + Several timedelta-like and DateOffset instances that are _not_ + compatible with Monthly or Annual frequencies. + """ return request.param @@ -45,7 +57,10 @@ def mismatched(request): np.timedelta64(72, 'h'), Timedelta('72:00:00')]) def three_days(request): - # several timedelta/offset-like objects representing a 3-day timedelta + """ + Several timedelta-like and DateOffset objects that each represent + a 3-day timedelta + """ return request.param @@ -56,7 +71,10 @@ def three_days(request): timedelta(minutes=120), np.timedelta64(120, 'm')]) def two_hours(request): - # several timedelta/offset-like objects representing a 2-hour timedelta + """ + Several timedelta-like and DateOffset objects that each represent + a 2-hour timedelta + """ return request.param From d93c11eb5880864757120c45f8776f808d615aa2 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Fri, 16 Feb 2018 16:33:10 -0800 Subject: [PATCH 7/7] requested docstring --- pandas/tests/indexes/period/test_arithmetic.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pandas/tests/indexes/period/test_arithmetic.py b/pandas/tests/indexes/period/test_arithmetic.py index 544bc9a96b999..5f8f9533e9c44 100644 --- a/pandas/tests/indexes/period/test_arithmetic.py +++ b/pandas/tests/indexes/period/test_arithmetic.py @@ -301,7 +301,10 @@ def test_pi_add_iadd_int(self, one): tm.assert_index_equal(rng, expected) def test_pi_sub_isub_int(self, one): - # int + """ + PeriodIndex.__sub__ and __isub__ with several representations of + the integer 1, e.g. int, long, np.int64, np.uint8, ... + """ rng = pd.period_range('2000-01-01 09:00', freq='H', periods=10) result = rng - one expected = pd.period_range('2000-01-01 08:00', freq='H', periods=10)