From 33a04f32ae87d0323f7b7dd98648175b65d630cb Mon Sep 17 00:00:00 2001 From: sinhrks Date: Sat, 30 Apr 2016 19:29:25 +0900 Subject: [PATCH] TST/ERR: Add Period ops tests / fix error message --- pandas/src/period.pyx | 9 +- pandas/tseries/tests/test_period.py | 426 ++++++++++++++++---------- pandas/tseries/tests/test_resample.py | 23 +- pandas/util/testing.py | 2 + 4 files changed, 276 insertions(+), 184 deletions(-) diff --git a/pandas/src/period.pyx b/pandas/src/period.pyx index 670fe1e4f168c..858aa58df8d7d 100644 --- a/pandas/src/period.pyx +++ b/pandas/src/period.pyx @@ -799,8 +799,8 @@ cdef class Period(object): else: ordinal = self.ordinal + (nanos // offset_nanos) return Period(ordinal=ordinal, freq=self.freq) - msg = 'Input cannnot be converted to Period(freq={0})' - raise ValueError(msg) + msg = 'Input cannot be converted to Period(freq={0})' + raise IncompatibleFrequency(msg.format(self.freqstr)) elif isinstance(other, offsets.DateOffset): freqstr = frequencies.get_standard_freq(other) base = frequencies.get_base_alias(freqstr) @@ -849,8 +849,8 @@ cdef class Period(object): return Period(ordinal=ordinal, freq=self.freq) elif isinstance(other, Period): if other.freq != self.freq: - raise ValueError("Cannot do arithmetic with " - "non-conforming periods") + msg = _DIFFERENT_FREQ.format(self.freqstr, other.freqstr) + raise IncompatibleFrequency(msg) if self.ordinal == tslib.iNaT or other.ordinal == tslib.iNaT: return Period(ordinal=tslib.iNaT, freq=self.freq) return self.ordinal - other.ordinal @@ -865,7 +865,6 @@ cdef class Period(object): else: return NotImplemented - def asfreq(self, freq, how='E'): """ Convert Period to desired frequency, either at the start or end of the diff --git a/pandas/tseries/tests/test_period.py b/pandas/tseries/tests/test_period.py index c5aae1f8ecebb..8ebdcc7acff2d 100644 --- a/pandas/tseries/tests/test_period.py +++ b/pandas/tseries/tests/test_period.py @@ -492,8 +492,8 @@ def test_sub_delta(self): result = left - right self.assertEqual(result, 4) - self.assertRaises(ValueError, left.__sub__, - Period('2007-01', freq='M')) + with self.assertRaises(period.IncompatibleFrequency): + left - Period('2007-01', freq='M') def test_to_timestamp(self): p = Period('1982', freq='A') @@ -829,9 +829,13 @@ def test_asfreq_MS(self): self.assertEqual(initial.asfreq(freq="M", how="S"), Period('2013-01', 'M')) - self.assertRaises(ValueError, initial.asfreq, freq="MS", how="S") - tm.assertRaisesRegexp(ValueError, "Unknown freqstr: MS", pd.Period, - '2013-01', 'MS') + + with self.assertRaisesRegexp(ValueError, "Unknown freqstr"): + initial.asfreq(freq="MS", how="S") + + with tm.assertRaisesRegexp(ValueError, "Unknown freqstr: MS"): + pd.Period('2013-01', 'MS') + self.assertTrue(_period_code_map.get("MS") is None) @@ -1638,7 +1642,7 @@ def test_constructor_use_start_freq(self): p = Period('4/2/2012', freq='B') index = PeriodIndex(start=p, periods=10) expected = PeriodIndex(start='4/2/2012', periods=10, freq='B') - self.assertTrue(index.equals(expected)) + tm.assert_index_equal(index, expected) def test_constructor_field_arrays(self): # GH #1264 @@ -1648,13 +1652,13 @@ def test_constructor_field_arrays(self): index = PeriodIndex(year=years, quarter=quarters, freq='Q-DEC') expected = period_range('1990Q3', '2009Q2', freq='Q-DEC') - self.assertTrue(index.equals(expected)) + tm.assert_index_equal(index, expected) index2 = PeriodIndex(year=years, quarter=quarters, freq='2Q-DEC') tm.assert_numpy_array_equal(index.asi8, index2.asi8) index = PeriodIndex(year=years, quarter=quarters) - self.assertTrue(index.equals(expected)) + tm.assert_index_equal(index, expected) years = [2007, 2007, 2007] months = [1, 2] @@ -1669,7 +1673,7 @@ def test_constructor_field_arrays(self): months = [1, 2, 3] idx = PeriodIndex(year=years, month=months, freq='M') exp = period_range('2007-01', periods=3, freq='M') - self.assertTrue(idx.equals(exp)) + tm.assert_index_equal(idx, exp) def test_constructor_U(self): # U was used as undefined period @@ -1700,7 +1704,7 @@ def test_constructor_corner(self): result = period_range('2007-01', periods=10.5, freq='M') exp = period_range('2007-01', periods=10, freq='M') - self.assertTrue(result.equals(exp)) + tm.assert_index_equal(result, exp) def test_constructor_fromarraylike(self): idx = period_range('2007-01', periods=20, freq='M') @@ -1711,29 +1715,29 @@ def test_constructor_fromarraylike(self): data=Period('2007', freq='A')) result = PeriodIndex(iter(idx)) - self.assertTrue(result.equals(idx)) + tm.assert_index_equal(result, idx) result = PeriodIndex(idx) - self.assertTrue(result.equals(idx)) + tm.assert_index_equal(result, idx) result = PeriodIndex(idx, freq='M') - self.assertTrue(result.equals(idx)) + tm.assert_index_equal(result, idx) result = PeriodIndex(idx, freq=offsets.MonthEnd()) - self.assertTrue(result.equals(idx)) + tm.assert_index_equal(result, idx) self.assertTrue(result.freq, 'M') result = PeriodIndex(idx, freq='2M') - self.assertTrue(result.equals(idx)) + tm.assert_index_equal(result, idx.asfreq('2M')) self.assertTrue(result.freq, '2M') result = PeriodIndex(idx, freq=offsets.MonthEnd(2)) - self.assertTrue(result.equals(idx)) + tm.assert_index_equal(result, idx.asfreq('2M')) self.assertTrue(result.freq, '2M') result = PeriodIndex(idx, freq='D') exp = idx.asfreq('D', 'e') - self.assertTrue(result.equals(exp)) + tm.assert_index_equal(result, exp) def test_constructor_datetime64arr(self): vals = np.arange(100000, 100000 + 10000, 100, dtype=np.int64) @@ -1744,10 +1748,10 @@ def test_constructor_datetime64arr(self): def test_constructor_simple_new(self): idx = period_range('2007-01', name='p', periods=2, freq='M') result = idx._simple_new(idx, 'p', freq=idx.freq) - self.assertTrue(result.equals(idx)) + tm.assert_index_equal(result, idx) result = idx._simple_new(idx.astype('i8'), 'p', freq=idx.freq) - self.assertTrue(result.equals(idx)) + tm.assert_index_equal(result, idx) result = idx._simple_new( [pd.Period('2007-01', freq='M'), pd.Period('2007-02', freq='M')], @@ -1801,14 +1805,14 @@ def test_constructor_freq_mult(self): for func in [PeriodIndex, period_range]: # must be the same, but for sure... pidx = func(start='2014-01', freq='2M', periods=4) - expected = PeriodIndex( - ['2014-01', '2014-03', '2014-05', '2014-07'], freq='M') + expected = PeriodIndex(['2014-01', '2014-03', + '2014-05', '2014-07'], freq='2M') tm.assert_index_equal(pidx, expected) pidx = func(start='2014-01-02', end='2014-01-15', freq='3D') expected = PeriodIndex(['2014-01-02', '2014-01-05', '2014-01-08', '2014-01-11', - '2014-01-14'], freq='D') + '2014-01-14'], freq='3D') tm.assert_index_equal(pidx, expected) pidx = func(end='2014-01-01 17:00', freq='4H', periods=3) @@ -1837,7 +1841,7 @@ def test_constructor_freq_mult_dti_compat(self): freqstr = str(mult) + freq pidx = PeriodIndex(start='2014-04-01', freq=freqstr, periods=10) expected = date_range(start='2014-04-01', freq=freqstr, - periods=10).to_period(freq) + periods=10).to_period(freqstr) tm.assert_index_equal(pidx, expected) def test_is_(self): @@ -1965,11 +1969,11 @@ def test_sub(self): result = rng - 5 exp = rng + (-5) - self.assertTrue(result.equals(exp)) + tm.assert_index_equal(result, exp) def test_periods_number_check(self): - self.assertRaises(ValueError, period_range, '2011-1-1', '2012-1-1', - 'B') + with tm.assertRaises(ValueError): + period_range('2011-1-1', '2012-1-1', 'B') def test_tolist(self): index = PeriodIndex(freq='A', start='1/1/2001', end='12/1/2009') @@ -1977,7 +1981,7 @@ def test_tolist(self): [tm.assertIsInstance(x, Period) for x in rs] recon = PeriodIndex(rs) - self.assertTrue(index.equals(recon)) + tm.assert_index_equal(index, recon) def test_to_timestamp(self): index = PeriodIndex(freq='A', start='1/1/2001', end='12/1/2009') @@ -1985,12 +1989,12 @@ def test_to_timestamp(self): exp_index = date_range('1/1/2001', end='12/31/2009', freq='A-DEC') result = series.to_timestamp(how='end') - self.assertTrue(result.index.equals(exp_index)) + tm.assert_index_equal(result.index, exp_index) self.assertEqual(result.name, 'foo') exp_index = date_range('1/1/2001', end='1/1/2009', freq='AS-JAN') result = series.to_timestamp(how='start') - self.assertTrue(result.index.equals(exp_index)) + tm.assert_index_equal(result.index, exp_index) def _get_with_delta(delta, freq='A-DEC'): return date_range(to_datetime('1/1/2001') + delta, @@ -1999,17 +2003,17 @@ def _get_with_delta(delta, freq='A-DEC'): delta = timedelta(hours=23) result = series.to_timestamp('H', 'end') exp_index = _get_with_delta(delta) - self.assertTrue(result.index.equals(exp_index)) + tm.assert_index_equal(result.index, exp_index) delta = timedelta(hours=23, minutes=59) result = series.to_timestamp('T', 'end') exp_index = _get_with_delta(delta) - self.assertTrue(result.index.equals(exp_index)) + tm.assert_index_equal(result.index, exp_index) result = series.to_timestamp('S', 'end') delta = timedelta(hours=23, minutes=59, seconds=59) exp_index = _get_with_delta(delta) - self.assertTrue(result.index.equals(exp_index)) + tm.assert_index_equal(result.index, exp_index) index = PeriodIndex(freq='H', start='1/1/2001', end='1/2/2001') series = Series(1, index=index, name='foo') @@ -2017,7 +2021,7 @@ def _get_with_delta(delta, freq='A-DEC'): exp_index = date_range('1/1/2001 00:59:59', end='1/2/2001 00:59:59', freq='H') result = series.to_timestamp(how='end') - self.assertTrue(result.index.equals(exp_index)) + tm.assert_index_equal(result.index, exp_index) self.assertEqual(result.name, 'foo') def test_to_timestamp_quarterly_bug(self): @@ -2028,7 +2032,7 @@ def test_to_timestamp_quarterly_bug(self): stamps = pindex.to_timestamp('D', 'end') expected = DatetimeIndex([x.to_timestamp('D', 'end') for x in pindex]) - self.assertTrue(stamps.equals(expected)) + tm.assert_index_equal(stamps, expected) def test_to_timestamp_preserve_name(self): index = PeriodIndex(freq='A', start='1/1/2001', end='12/1/2009', @@ -2054,11 +2058,11 @@ def test_to_timestamp_pi_nat(self): result = index.to_timestamp('D') expected = DatetimeIndex([pd.NaT, datetime(2011, 1, 1), datetime(2011, 2, 1)], name='idx') - self.assertTrue(result.equals(expected)) + tm.assert_index_equal(result, expected) self.assertEqual(result.name, 'idx') result2 = result.to_period(freq='M') - self.assertTrue(result2.equals(index)) + tm.assert_index_equal(result2, index) self.assertEqual(result2.name, 'idx') result3 = result.to_period(freq='3M') @@ -2085,12 +2089,12 @@ def test_to_timestamp_pi_mult(self): def test_start_time(self): index = PeriodIndex(freq='M', start='2016-01-01', end='2016-05-31') expected_index = date_range('2016-01-01', end='2016-05-31', freq='MS') - self.assertTrue(index.start_time.equals(expected_index)) + tm.assert_index_equal(index.start_time, expected_index) def test_end_time(self): index = PeriodIndex(freq='M', start='2016-01-01', end='2016-05-31') expected_index = date_range('2016-01-01', end='2016-05-31', freq='M') - self.assertTrue(index.end_time.equals(expected_index)) + tm.assert_index_equal(index.end_time, expected_index) def test_as_frame_columns(self): rng = period_range('1/1/2000', periods=5) @@ -2115,17 +2119,18 @@ def test_indexing(self): self.assertEqual(expected, result) def test_frame_setitem(self): - rng = period_range('1/1/2000', periods=5) - rng.name = 'index' + rng = period_range('1/1/2000', periods=5, name='index') df = DataFrame(randn(5, 3), index=rng) df['Index'] = rng rs = Index(df['Index']) - self.assertTrue(rs.equals(rng)) + tm.assert_index_equal(rs, rng, check_names=False) + self.assertEqual(rs.name, 'Index') + self.assertEqual(rng.name, 'index') rs = df.reset_index().set_index('index') tm.assertIsInstance(rs.index, PeriodIndex) - self.assertTrue(rs.index.equals(rng)) + tm.assert_index_equal(rs.index, rng) def test_period_set_index_reindex(self): # GH 6631 @@ -2134,9 +2139,9 @@ def test_period_set_index_reindex(self): idx2 = period_range('2013', periods=6, freq='A') df = df.set_index(idx1) - self.assertTrue(df.index.equals(idx1)) + tm.assert_index_equal(df.index, idx1) df = df.set_index(idx2) - self.assertTrue(df.index.equals(idx2)) + tm.assert_index_equal(df.index, idx2) def test_frame_to_time_stamp(self): K = 5 @@ -2146,12 +2151,12 @@ def test_frame_to_time_stamp(self): exp_index = date_range('1/1/2001', end='12/31/2009', freq='A-DEC') result = df.to_timestamp('D', 'end') - self.assertTrue(result.index.equals(exp_index)) + tm.assert_index_equal(result.index, exp_index) assert_almost_equal(result.values, df.values) exp_index = date_range('1/1/2001', end='1/1/2009', freq='AS-JAN') result = df.to_timestamp('D', 'start') - self.assertTrue(result.index.equals(exp_index)) + tm.assert_index_equal(result.index, exp_index) def _get_with_delta(delta, freq='A-DEC'): return date_range(to_datetime('1/1/2001') + delta, @@ -2160,44 +2165,44 @@ def _get_with_delta(delta, freq='A-DEC'): delta = timedelta(hours=23) result = df.to_timestamp('H', 'end') exp_index = _get_with_delta(delta) - self.assertTrue(result.index.equals(exp_index)) + tm.assert_index_equal(result.index, exp_index) delta = timedelta(hours=23, minutes=59) result = df.to_timestamp('T', 'end') exp_index = _get_with_delta(delta) - self.assertTrue(result.index.equals(exp_index)) + tm.assert_index_equal(result.index, exp_index) result = df.to_timestamp('S', 'end') delta = timedelta(hours=23, minutes=59, seconds=59) exp_index = _get_with_delta(delta) - self.assertTrue(result.index.equals(exp_index)) + tm.assert_index_equal(result.index, exp_index) # columns df = df.T exp_index = date_range('1/1/2001', end='12/31/2009', freq='A-DEC') result = df.to_timestamp('D', 'end', axis=1) - self.assertTrue(result.columns.equals(exp_index)) + tm.assert_index_equal(result.columns, exp_index) assert_almost_equal(result.values, df.values) exp_index = date_range('1/1/2001', end='1/1/2009', freq='AS-JAN') result = df.to_timestamp('D', 'start', axis=1) - self.assertTrue(result.columns.equals(exp_index)) + tm.assert_index_equal(result.columns, exp_index) delta = timedelta(hours=23) result = df.to_timestamp('H', 'end', axis=1) exp_index = _get_with_delta(delta) - self.assertTrue(result.columns.equals(exp_index)) + tm.assert_index_equal(result.columns, exp_index) delta = timedelta(hours=23, minutes=59) result = df.to_timestamp('T', 'end', axis=1) exp_index = _get_with_delta(delta) - self.assertTrue(result.columns.equals(exp_index)) + tm.assert_index_equal(result.columns, exp_index) result = df.to_timestamp('S', 'end', axis=1) delta = timedelta(hours=23, minutes=59, seconds=59) exp_index = _get_with_delta(delta) - self.assertTrue(result.columns.equals(exp_index)) + tm.assert_index_equal(result.columns, exp_index) # invalid axis assertRaisesRegexp(ValueError, 'axis', df.to_timestamp, axis=2) @@ -2351,7 +2356,7 @@ def test_shift(self): pi1 = PeriodIndex(freq='A', start='1/1/2001', end='12/1/2009') pi2 = PeriodIndex(freq='A', start='1/1/2002', end='12/1/2010') - self.assertTrue(pi1.shift(0).equals(pi1)) + tm.assert_index_equal(pi1.shift(0), pi1) assert_equal(len(pi1), len(pi2)) assert_equal(pi1.shift(1).values, pi2.values) @@ -2385,25 +2390,25 @@ def test_shift_nat(self): 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') - self.assertTrue(result.equals(expected)) + expected = PeriodIndex(['2011-02', '2011-03', 'NaT', + '2011-05'], freq='M', name='idx') + tm.assert_index_equal(result, expected) self.assertEqual(result.name, expected.name) def test_shift_ndarray(self): 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') - self.assertTrue(result.equals(expected)) + 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') result = idx.shift(np.array([1, -2, 3, -4])) - expected = PeriodIndex( - ['2011-02', '2010-12', 'NaT', '2010-12'], freq='M', name='idx') - self.assertTrue(result.equals(expected)) + expected = PeriodIndex(['2011-02', '2010-12', 'NaT', + '2010-12'], freq='M', name='idx') + tm.assert_index_equal(result, expected) def test_asfreq(self): pi1 = PeriodIndex(freq='A', start='1/1/2001', end='1/1/2001') @@ -2477,7 +2482,7 @@ def test_asfreq_nat(self): idx = PeriodIndex(['2011-01', '2011-02', 'NaT', '2011-04'], freq='M') result = idx.asfreq(freq='Q') expected = PeriodIndex(['2011Q1', '2011Q1', 'NaT', '2011Q2'], freq='Q') - self.assertTrue(result.equals(expected)) + tm.assert_index_equal(result, expected) def test_asfreq_mult_pi(self): pi = PeriodIndex(['2001-01', '2001-02', 'NaT', '2001-03'], freq='2M') @@ -2576,12 +2581,12 @@ def test_asfreq_ts(self): df_result = df.asfreq('D', how='end') exp_index = index.asfreq('D', how='end') self.assertEqual(len(result), len(ts)) - self.assertTrue(result.index.equals(exp_index)) - self.assertTrue(df_result.index.equals(exp_index)) + tm.assert_index_equal(result.index, exp_index) + tm.assert_index_equal(df_result.index, exp_index) result = ts.asfreq('D', how='start') self.assertEqual(len(result), len(ts)) - self.assertTrue(result.index.equals(index.asfreq('D', how='start'))) + tm.assert_index_equal(result.index, index.asfreq('D', how='start')) def test_badinput(self): self.assertRaises(datetools.DateParseError, Period, '1/1/-2000', 'A') @@ -2783,11 +2788,11 @@ def test_pindex_qaccess(self): def test_period_dt64_round_trip(self): dti = date_range('1/1/2000', '1/7/2002', freq='B') pi = dti.to_period() - self.assertTrue(pi.to_timestamp().equals(dti)) + tm.assert_index_equal(pi.to_timestamp(), dti) dti = date_range('1/1/2000', '1/7/2002', freq='B') pi = dti.to_period(freq='H') - self.assertTrue(pi.to_timestamp().equals(dti)) + tm.assert_index_equal(pi.to_timestamp(), dti) def test_to_period_quarterly(self): # make sure we can make the round trip @@ -2796,7 +2801,7 @@ def test_to_period_quarterly(self): rng = period_range('1989Q3', '1991Q3', freq=freq) stamps = rng.to_timestamp() result = stamps.to_period(freq) - self.assertTrue(rng.equals(result)) + tm.assert_index_equal(rng, result) def test_to_period_quarterlyish(self): offsets = ['BQ', 'QS', 'BQS'] @@ -2841,7 +2846,7 @@ def test_multiples(self): def test_pindex_multiples(self): pi = PeriodIndex(start='1/1/11', end='12/31/11', freq='2M') expected = PeriodIndex(['2011-01', '2011-03', '2011-05', '2011-07', - '2011-09', '2011-11'], freq='M') + '2011-09', '2011-11'], freq='2M') tm.assert_index_equal(pi, expected) self.assertEqual(pi.freq, offsets.MonthEnd(2)) self.assertEqual(pi.freqstr, '2M') @@ -2874,7 +2879,7 @@ def test_take(self): taken2 = index[[5, 6, 8, 12]] for taken in [taken1, taken2]: - self.assertTrue(taken.equals(expected)) + tm.assert_index_equal(taken, expected) tm.assertIsInstance(taken, PeriodIndex) self.assertEqual(taken.freq, index.freq) self.assertEqual(taken.name, expected.name) @@ -2954,7 +2959,7 @@ def test_align_series(self): for kind in ['inner', 'outer', 'left', 'right']: ts.align(ts[::2], join=kind) msg = "Input has different freq=D from PeriodIndex\\(freq=A-DEC\\)" - with assertRaisesRegexp(ValueError, msg): + with assertRaisesRegexp(period.IncompatibleFrequency, msg): ts + ts.asfreq('D', how="end") def test_align_frame(self): @@ -2973,11 +2978,11 @@ def test_union(self): index = period_range('1/1/2000', '1/20/2000', freq='D') result = index[:-5].union(index[10:]) - self.assertTrue(result.equals(index)) + tm.assert_index_equal(result, index) # not in order result = _permute(index[:-5]).union(_permute(index[10:])) - self.assertTrue(result.equals(index)) + tm.assert_index_equal(result, index) # raise if different frequencies index = period_range('1/1/2000', '1/20/2000', freq='D') @@ -3008,13 +3013,13 @@ def test_intersection(self): index = period_range('1/1/2000', '1/20/2000', freq='D') result = index[:-5].intersection(index[10:]) - self.assertTrue(result.equals(index[10:-5])) + tm.assert_index_equal(result, index[10:-5]) # not in order left = _permute(index[:-5]) right = _permute(index[10:]) result = left.intersection(right).sort_values() - self.assertTrue(result.equals(index[10:-5])) + tm.assert_index_equal(result, index[10:-5]) # raise if different frequencies index = period_range('1/1/2000', '1/20/2000', freq='D') @@ -3045,7 +3050,7 @@ def test_intersection_cases(self): for (rng, expected) in [(rng2, expected2), (rng3, expected3), (rng4, expected4)]: result = base.intersection(rng) - self.assertTrue(result.equals(expected)) + tm.assert_index_equal(result, expected) self.assertEqual(result.name, expected.name) self.assertEqual(result.freq, expected.freq) @@ -3071,7 +3076,7 @@ def test_intersection_cases(self): for (rng, expected) in [(rng2, expected2), (rng3, expected3), (rng4, expected4)]: result = base.intersection(rng) - self.assertTrue(result.equals(expected)) + tm.assert_index_equal(result, expected) self.assertEqual(result.name, expected.name) self.assertEqual(result.freq, 'D') @@ -3151,7 +3156,7 @@ def test_map(self): index = PeriodIndex([2005, 2007, 2009], freq='A') result = index.map(lambda x: x + 1) expected = index + 1 - self.assertTrue(result.equals(expected)) + tm.assert_index_equal(result, expected) result = index.map(lambda x: x.ordinal) exp = [x.ordinal for x in index] @@ -3252,11 +3257,11 @@ def test_factorize(self): arr, idx = idx1.factorize() self.assert_numpy_array_equal(arr, exp_arr) - self.assertTrue(idx.equals(exp_idx)) + tm.assert_index_equal(idx, exp_idx) arr, idx = idx1.factorize(sort=True) self.assert_numpy_array_equal(arr, exp_arr) - self.assertTrue(idx.equals(exp_idx)) + tm.assert_index_equal(idx, exp_idx) idx2 = pd.PeriodIndex(['2014-03', '2014-03', '2014-02', '2014-01', '2014-03', '2014-01'], freq='M') @@ -3264,19 +3269,19 @@ def test_factorize(self): exp_arr = np.array([2, 2, 1, 0, 2, 0]) arr, idx = idx2.factorize(sort=True) self.assert_numpy_array_equal(arr, exp_arr) - self.assertTrue(idx.equals(exp_idx)) + tm.assert_index_equal(idx, exp_idx) exp_arr = np.array([0, 0, 1, 2, 0, 2]) exp_idx = PeriodIndex(['2014-03', '2014-02', '2014-01'], freq='M') arr, idx = idx2.factorize() self.assert_numpy_array_equal(arr, exp_arr) - self.assertTrue(idx.equals(exp_idx)) + tm.assert_index_equal(idx, exp_idx) def test_recreate_from_data(self): for o in ['M', 'Q', 'A', 'D', 'B', 'T', 'S', 'L', 'U', 'N', 'H']: org = PeriodIndex(start='2001/04/01', freq=o, periods=1) idx = PeriodIndex(org.values, freq=o) - self.assertTrue(idx.equals(org)) + tm.assert_index_equal(idx, org) def test_combine_first(self): # GH 3367 @@ -3324,7 +3329,6 @@ def _permute(obj): class TestMethods(tm.TestCase): - "Base test class for MaskedArrays." def test_add(self): dt1 = Period(freq='D', year=2008, month=1, day=1) @@ -3356,6 +3360,17 @@ def test_add_raises(self): with tm.assertRaisesRegexp(TypeError, msg): dt1 + dt2 + def test_sub(self): + dt1 = Period('2011-01-01', freq='D') + dt2 = Period('2011-01-15', freq='D') + + self.assertEqual(dt1 - dt2, -14) + self.assertEqual(dt2 - dt1, 14) + + msg = "Input has different freq=M from Period\(freq=D\)" + with tm.assertRaisesRegexp(period.IncompatibleFrequency, msg): + dt1 - pd.Period('2011-02', freq='M') + def test_add_offset(self): # freq is DateOffset for freq in ['A', '2A', '3A']: @@ -3367,14 +3382,14 @@ def test_add_offset(self): for o in [offsets.YearBegin(2), offsets.MonthBegin(1), offsets.Minute(), np.timedelta64(365, 'D'), timedelta(365)]: - with tm.assertRaises(ValueError): + with tm.assertRaises(period.IncompatibleFrequency): p + o if isinstance(o, np.timedelta64): with tm.assertRaises(TypeError): o + p else: - with tm.assertRaises(ValueError): + with tm.assertRaises(period.IncompatibleFrequency): o + p for freq in ['M', '2M', '3M']: @@ -3390,14 +3405,14 @@ def test_add_offset(self): for o in [offsets.YearBegin(2), offsets.MonthBegin(1), offsets.Minute(), np.timedelta64(365, 'D'), timedelta(365)]: - with tm.assertRaises(ValueError): + with tm.assertRaises(period.IncompatibleFrequency): p + o if isinstance(o, np.timedelta64): with tm.assertRaises(TypeError): o + p else: - with tm.assertRaises(ValueError): + with tm.assertRaises(period.IncompatibleFrequency): o + p # freq is Tick @@ -3433,14 +3448,14 @@ def test_add_offset(self): for o in [offsets.YearBegin(2), offsets.MonthBegin(1), offsets.Minute(), np.timedelta64(4, 'h'), timedelta(hours=23)]: - with tm.assertRaises(ValueError): + with tm.assertRaises(period.IncompatibleFrequency): p + o if isinstance(o, np.timedelta64): with tm.assertRaises(TypeError): o + p else: - with tm.assertRaises(ValueError): + with tm.assertRaises(period.IncompatibleFrequency): o + p for freq in ['H', '2H', '3H']: @@ -3475,14 +3490,14 @@ def test_add_offset(self): for o in [offsets.YearBegin(2), offsets.MonthBegin(1), offsets.Minute(), np.timedelta64(3200, 's'), timedelta(hours=23, minutes=30)]: - with tm.assertRaises(ValueError): + with tm.assertRaises(period.IncompatibleFrequency): p + o if isinstance(o, np.timedelta64): with tm.assertRaises(TypeError): o + p else: - with tm.assertRaises(ValueError): + with tm.assertRaises(period.IncompatibleFrequency): o + p def test_add_offset_nat(self): @@ -3496,14 +3511,14 @@ def test_add_offset_nat(self): for o in [offsets.YearBegin(2), offsets.MonthBegin(1), offsets.Minute(), np.timedelta64(365, 'D'), timedelta(365)]: - with tm.assertRaises(ValueError): + with tm.assertRaises(period.IncompatibleFrequency): p + o if isinstance(o, np.timedelta64): with tm.assertRaises(TypeError): o + p else: - with tm.assertRaises(ValueError): + with tm.assertRaises(period.IncompatibleFrequency): o + p for freq in ['M', '2M', '3M']: @@ -3520,14 +3535,14 @@ def test_add_offset_nat(self): for o in [offsets.YearBegin(2), offsets.MonthBegin(1), offsets.Minute(), np.timedelta64(365, 'D'), timedelta(365)]: - with tm.assertRaises(ValueError): + with tm.assertRaises(period.IncompatibleFrequency): p + o if isinstance(o, np.timedelta64): with tm.assertRaises(TypeError): o + p else: - with tm.assertRaises(ValueError): + with tm.assertRaises(period.IncompatibleFrequency): o + p # freq is Tick for freq in ['D', '2D', '3D']: @@ -3547,14 +3562,14 @@ def test_add_offset_nat(self): offsets.Minute(), np.timedelta64(4, 'h'), timedelta(hours=23)]: - with tm.assertRaises(ValueError): + with tm.assertRaises(period.IncompatibleFrequency): p + o if isinstance(o, np.timedelta64): with tm.assertRaises(TypeError): o + p else: - with tm.assertRaises(ValueError): + with tm.assertRaises(period.IncompatibleFrequency): o + p for freq in ['H', '2H', '3H']: @@ -3570,14 +3585,14 @@ def test_add_offset_nat(self): for o in [offsets.YearBegin(2), offsets.MonthBegin(1), offsets.Minute(), np.timedelta64(3200, 's'), timedelta(hours=23, minutes=30)]: - with tm.assertRaises(ValueError): + with tm.assertRaises(period.IncompatibleFrequency): p + o if isinstance(o, np.timedelta64): with tm.assertRaises(TypeError): o + p else: - with tm.assertRaises(ValueError): + with tm.assertRaises(period.IncompatibleFrequency): o + p def test_sub_pdnat(self): @@ -3599,7 +3614,7 @@ def test_sub_offset(self): for o in [offsets.YearBegin(2), offsets.MonthBegin(1), offsets.Minute(), np.timedelta64(365, 'D'), timedelta(365)]: - with tm.assertRaises(ValueError): + with tm.assertRaises(period.IncompatibleFrequency): p - o for freq in ['M', '2M', '3M']: @@ -3612,7 +3627,7 @@ def test_sub_offset(self): for o in [offsets.YearBegin(2), offsets.MonthBegin(1), offsets.Minute(), np.timedelta64(365, 'D'), timedelta(365)]: - with tm.assertRaises(ValueError): + with tm.assertRaises(period.IncompatibleFrequency): p - o # freq is Tick @@ -3634,7 +3649,7 @@ def test_sub_offset(self): for o in [offsets.YearBegin(2), offsets.MonthBegin(1), offsets.Minute(), np.timedelta64(4, 'h'), timedelta(hours=23)]: - with tm.assertRaises(ValueError): + with tm.assertRaises(period.IncompatibleFrequency): p - o for freq in ['H', '2H', '3H']: @@ -3655,7 +3670,7 @@ def test_sub_offset(self): for o in [offsets.YearBegin(2), offsets.MonthBegin(1), offsets.Minute(), np.timedelta64(3200, 's'), timedelta(hours=23, minutes=30)]: - with tm.assertRaises(ValueError): + with tm.assertRaises(period.IncompatibleFrequency): p - o def test_sub_offset_nat(self): @@ -3668,7 +3683,7 @@ def test_sub_offset_nat(self): for o in [offsets.YearBegin(2), offsets.MonthBegin(1), offsets.Minute(), np.timedelta64(365, 'D'), timedelta(365)]: - with tm.assertRaises(ValueError): + with tm.assertRaises(period.IncompatibleFrequency): p - o for freq in ['M', '2M', '3M']: @@ -3679,7 +3694,7 @@ def test_sub_offset_nat(self): for o in [offsets.YearBegin(2), offsets.MonthBegin(1), offsets.Minute(), np.timedelta64(365, 'D'), timedelta(365)]: - with tm.assertRaises(ValueError): + with tm.assertRaises(period.IncompatibleFrequency): p - o # freq is Tick @@ -3693,7 +3708,7 @@ def test_sub_offset_nat(self): for o in [offsets.YearBegin(2), offsets.MonthBegin(1), offsets.Minute(), np.timedelta64(4, 'h'), timedelta(hours=23)]: - with tm.assertRaises(ValueError): + with tm.assertRaises(period.IncompatibleFrequency): p - o for freq in ['H', '2H', '3H']: @@ -3706,7 +3721,7 @@ def test_sub_offset_nat(self): for o in [offsets.YearBegin(2), offsets.MonthBegin(1), offsets.Minute(), np.timedelta64(3200, 's'), timedelta(hours=23, minutes=30)]: - with tm.assertRaises(ValueError): + with tm.assertRaises(period.IncompatibleFrequency): p - o def test_nat_ops(self): @@ -3715,77 +3730,153 @@ def test_nat_ops(self): self.assertEqual((p + 1).ordinal, tslib.iNaT) self.assertEqual((1 + p).ordinal, tslib.iNaT) self.assertEqual((p - 1).ordinal, tslib.iNaT) - self.assertEqual( - (p - Period('2011-01', freq=freq)).ordinal, tslib.iNaT) - self.assertEqual( - (Period('2011-01', freq=freq) - p).ordinal, tslib.iNaT) + self.assertEqual((p - Period('2011-01', freq=freq)).ordinal, + tslib.iNaT) + self.assertEqual((Period('2011-01', freq=freq) - p).ordinal, + tslib.iNaT) + + def test_period_ops_offset(self): + p = Period('2011-04-01', freq='D') + result = p + offsets.Day() + exp = pd.Period('2011-04-02', freq='D') + self.assertEqual(result, exp) - def test_pi_ops_nat(self): - idx = PeriodIndex(['2011-01', '2011-02', 'NaT', + result = p - offsets.Day(2) + exp = pd.Period('2011-03-30', freq='D') + self.assertEqual(result, exp) + + msg = "Input cannot be converted to Period\(freq=D\)" + with tm.assertRaisesRegexp(period.IncompatibleFrequency, msg): + p + offsets.Hour(2) + + with tm.assertRaisesRegexp(period.IncompatibleFrequency, msg): + p - offsets.Hour(2) + + +class TestPeriodIndexSeriesMethods(tm.TestCase): + """ Test PeriodIndex and Period Series Ops consistency """ + + def _check(self, values, func, expected): + idx = pd.PeriodIndex(values) + result = func(idx) + tm.assert_index_equal(result, pd.PeriodIndex(expected)) + + s = pd.Series(values) + result = func(s) + + exp = pd.Series(expected) + # Period(NaT) != Period(NaT) + + lmask = result.map(lambda x: x.ordinal != tslib.iNaT) + rmask = exp.map(lambda x: x.ordinal != tslib.iNaT) + tm.assert_series_equal(lmask, rmask) + tm.assert_series_equal(result[lmask], exp[rmask]) + + def test_pi_ops(self): + idx = PeriodIndex(['2011-01', '2011-02', '2011-03', '2011-04'], freq='M', name='idx') - result = idx + 2 - expected = PeriodIndex( - ['2011-03', '2011-04', 'NaT', '2011-06'], freq='M', name='idx') - self.assertTrue(result.equals(expected)) - result2 = result - 2 - self.assertTrue(result2.equals(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) + + self._check(idx + 2, lambda x: x - 2, idx) + result = idx - Period('2011-01', freq='M') + exp = pd.Index([0, 1, 2, 3], name='idx') + tm.assert_index_equal(result, exp) + + result = Period('2011-01', freq='M') - idx + exp = pd.Index([0, -1, -2, -3], name='idx') + 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) msg = "unsupported operand type\(s\)" - with tm.assertRaisesRegexp(TypeError, msg): - idx + "str" + for obj in [idx, s]: + for ng in ["str", 1.5]: + with tm.assertRaisesRegexp(TypeError, msg): + obj + ng + + with tm.assertRaises(TypeError): + # error message differs between PY2 and 3 + ng + obj - def test_pi_ops_array(self): + with tm.assertRaisesRegexp(TypeError, msg): + obj - ng + + def test_pi_ops_nat(self): idx = PeriodIndex(['2011-01', '2011-02', 'NaT', '2011-04'], freq='M', name='idx') - result = idx + np.array([1, 2, 3, 4]) + 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 + 2, lambda x: x - 2, idx) + + def test_pi_ops_array_int(self): + 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') - self.assert_index_equal(result, exp) + self._check(idx, f, exp) - result = np.add(idx, np.array([4, -1, 1, 2])) + 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') - self.assert_index_equal(result, exp) + self._check(idx, f, exp) - result = idx - np.array([1, 2, 3, 4]) + f = lambda x: x - np.array([1, 2, 3, 4]) exp = PeriodIndex(['2010-12', '2010-12', 'NaT', '2010-12'], freq='M', name='idx') - self.assert_index_equal(result, exp) + self._check(idx, f, exp) - result = np.subtract(idx, np.array([3, 2, 3, -2])) + 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') - self.assert_index_equal(result, exp) - - # incompatible freq - msg = "Input has different freq from PeriodIndex\(freq=M\)" - with tm.assertRaisesRegexp(period.IncompatibleFrequency, msg): - idx + np.array([np.timedelta64(1, 'D')] * 4) - - idx = PeriodIndex(['2011-01-01 09:00', '2011-01-01 10:00', 'NaT', - '2011-01-01 12:00'], freq='H', name='idx') - result = idx + np.array([np.timedelta64(1, 'D')] * 4) - exp = PeriodIndex(['2011-01-02 09:00', '2011-01-02 10:00', 'NaT', - '2011-01-02 12:00'], freq='H', name='idx') - self.assert_index_equal(result, exp) - - result = idx - np.array([np.timedelta64(1, 'h')] * 4) - exp = PeriodIndex(['2011-01-01 08:00', '2011-01-01 09:00', 'NaT', - '2011-01-01 11:00'], freq='H', name='idx') - self.assert_index_equal(result, exp) + self._check(idx, f, exp) + + def test_pi_ops_offset(self): + idx = PeriodIndex(['2011-01-01', '2011-02-01', '2011-03-01', + '2011-04-01'], freq='D', name='idx') + f = lambda x: x + offsets.Day() + exp = PeriodIndex(['2011-01-02', '2011-02-02', '2011-03-02', + '2011-04-02'], freq='D', name='idx') + self._check(idx, f, exp) + + f = lambda x: x + offsets.Day(2) + exp = PeriodIndex(['2011-01-03', '2011-02-03', '2011-03-03', + '2011-04-03'], freq='D', name='idx') + self._check(idx, f, exp) + + f = lambda x: x - offsets.Day(2) + exp = PeriodIndex(['2010-12-30', '2011-01-30', '2011-02-27', + '2011-03-30'], freq='D', name='idx') + self._check(idx, f, exp) + + 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) + + # Series op is applied per Period instance, thus error is raised + # from Period + msg_idx = "Input has different freq from PeriodIndex\(freq=D\)" + msg_s = "Input cannot be converted to Period\(freq=D\)" + for obj, msg in [(idx, msg_idx), (s, msg_s)]: + with tm.assertRaisesRegexp(period.IncompatibleFrequency, msg): + obj + offsets.Hour(2) - msg = "Input has different freq from PeriodIndex\(freq=H\)" - with tm.assertRaisesRegexp(period.IncompatibleFrequency, msg): - idx + np.array([np.timedelta64(1, 's')] * 4) + with tm.assertRaisesRegexp(period.IncompatibleFrequency, msg): + offsets.Hour(2) + obj - idx = PeriodIndex(['2011-01-01 09:00:00', '2011-01-01 10:00:00', 'NaT', - '2011-01-01 12:00:00'], freq='S', name='idx') - result = idx + np.array([np.timedelta64(1, 'h'), np.timedelta64( - 30, 's'), np.timedelta64(2, 'h'), np.timedelta64(15, 'm')]) - exp = PeriodIndex(['2011-01-01 10:00:00', '2011-01-01 10:00:30', 'NaT', - '2011-01-01 12:15:00'], freq='S', name='idx') - self.assert_index_equal(result, exp) + with tm.assertRaisesRegexp(period.IncompatibleFrequency, msg): + obj - offsets.Hour(2) def test_pi_sub_period(self): # GH 13071 @@ -3903,7 +3994,7 @@ def test_equal(self): self.assertEqual(self.january1, self.january2) def test_equal_Raises_Value(self): - with tm.assertRaises(ValueError): + with tm.assertRaises(period.IncompatibleFrequency): self.january1 == self.day def test_notEqual(self): @@ -3914,7 +4005,7 @@ def test_greater(self): self.assertTrue(self.february > self.january1) def test_greater_Raises_Value(self): - with tm.assertRaises(ValueError): + with tm.assertRaises(period.IncompatibleFrequency): self.january1 > self.day def test_greater_Raises_Type(self): @@ -3925,8 +4016,9 @@ def test_greaterEqual(self): self.assertTrue(self.january1 >= self.january2) def test_greaterEqual_Raises_Value(self): - with tm.assertRaises(ValueError): + with tm.assertRaises(period.IncompatibleFrequency): self.january1 >= self.day + with tm.assertRaises(TypeError): print(self.january1 >= 1) @@ -3934,7 +4026,7 @@ def test_smallerEqual(self): self.assertTrue(self.january1 <= self.january2) def test_smallerEqual_Raises_Value(self): - with tm.assertRaises(ValueError): + with tm.assertRaises(period.IncompatibleFrequency): self.january1 <= self.day def test_smallerEqual_Raises_Type(self): @@ -3945,7 +4037,7 @@ def test_smaller(self): self.assertTrue(self.january1 < self.february) def test_smaller_Raises_Value(self): - with tm.assertRaises(ValueError): + with tm.assertRaises(period.IncompatibleFrequency): self.january1 < self.day def test_smaller_Raises_Type(self): @@ -4033,7 +4125,7 @@ def test_pi_pi_comp(self): with tm.assertRaisesRegexp(period.IncompatibleFrequency, msg): Period('2011', freq='A') >= base - with tm.assertRaisesRegexp(ValueError, msg): + with tm.assertRaisesRegexp(period.IncompatibleFrequency, msg): idx = PeriodIndex(['2011', '2012', '2013', '2014'], freq='A') base <= idx diff --git a/pandas/tseries/tests/test_resample.py b/pandas/tseries/tests/test_resample.py index 37b16684643be..8e6341c6b7cc3 100644 --- a/pandas/tseries/tests/test_resample.py +++ b/pandas/tseries/tests/test_resample.py @@ -637,13 +637,13 @@ def test_resample_empty_series(self): methods = [method for method in resample_methods if method != 'ohlc'] for method in methods: - expected_index = s.index._shallow_copy(freq=freq) - result = getattr(s.resample(freq), method)() - expected = s - assert_index_equal(result.index, expected_index) - # freq equality not yet checked in assert_index_equal - self.assertEqual(result.index.freq, expected_index.freq) + + expected = s.copy() + expected.index = s.index._shallow_copy(freq=freq) + assert_index_equal(result.index, expected.index) + self.assertEqual(result.index.freq, expected.index.freq) + if (method == 'size' and isinstance(result.index, PeriodIndex) and freq in ['M', 'D']): @@ -665,13 +665,12 @@ def test_resample_empty_dataframe(self): # count retains dimensions too methods = downsample_methods + ['count'] for method in methods: - expected_index = f.index._shallow_copy(freq=freq) result = getattr(f.resample(freq), method)() - expected = f - assert_index_equal(result.index, expected_index) - # freq equality not yet checked in assert_index_equal - # TODO: remove when freq checked - self.assertEqual(result.index.freq, expected_index.freq) + + expected = f.copy() + expected.index = f.index._shallow_copy(freq=freq) + assert_index_equal(result.index, expected.index) + self.assertEqual(result.index.freq, expected.index.freq) assert_frame_equal(result, expected, check_dtype=False) # test size for GH13212 (currently stays as df) diff --git a/pandas/util/testing.py b/pandas/util/testing.py index 8682302b542be..73063675ebfec 100644 --- a/pandas/util/testing.py +++ b/pandas/util/testing.py @@ -751,6 +751,8 @@ def _get_ilevel_values(index, level): # metadata comparison if check_names: assert_attr_equal('names', left, right, obj=obj) + if isinstance(left, pd.PeriodIndex) or isinstance(right, pd.PeriodIndex): + assert_attr_equal('freq', left, right, obj=obj) def assert_class_equal(left, right, exact=True, obj='Input'):