diff --git a/doc/source/api.rst b/doc/source/api.rst index 93edd090d846b..b5798a02e7852 100644 --- a/doc/source/api.rst +++ b/doc/source/api.rst @@ -1775,6 +1775,7 @@ Conversion .. autosummary:: :toctree: generated/ + DatetimeIndex.set_freq DatetimeIndex.to_period DatetimeIndex.to_perioddelta DatetimeIndex.to_pydatetime @@ -1808,6 +1809,7 @@ Conversion .. autosummary:: :toctree: generated/ + TimedeltaIndex.set_freq TimedeltaIndex.to_pytimedelta TimedeltaIndex.to_series TimedeltaIndex.round diff --git a/doc/source/whatsnew/v0.23.0.txt b/doc/source/whatsnew/v0.23.0.txt index 4ad40fe0f7f2b..bc543db8a44d9 100644 --- a/doc/source/whatsnew/v0.23.0.txt +++ b/doc/source/whatsnew/v0.23.0.txt @@ -524,6 +524,7 @@ Other Enhancements - Added new writer for exporting Stata dta files in version 117, ``StataWriter117``. This format supports exporting strings with lengths up to 2,000,000 characters (:issue:`16450`) - :func:`to_hdf` and :func:`read_hdf` now accept an ``errors`` keyword argument to control encoding error handling (:issue:`20835`) - :func:`date_range` now returns a linearly spaced ``DatetimeIndex`` if ``start``, ``stop``, and ``periods`` are specified, but ``freq`` is not. (:issue:`20808`) +- :meth:`DatetimeIndex.set_freq` and :meth:`TimedeltaIndex.set_freq` are now available for setting the ``.freq`` attribute (:issue:`20886`) .. _whatsnew_0230.api_breaking: @@ -998,6 +999,7 @@ Deprecations - Setting ``PeriodIndex.freq`` (which was not guaranteed to work correctly) is deprecated. Use :meth:`PeriodIndex.asfreq` instead (:issue:`20678`) - ``Index.get_duplicates()`` is deprecated and will be removed in a future version (:issue:`20239`) - The previous default behavior of negative indices in ``Categorical.take`` is deprecated. In a future version it will change from meaning missing values to meaning positional indices from the right. The future behavior is consistent with :meth:`Series.take` (:issue:`20664`). +- Setting the ``.freq`` attribute is deprecated for :class:`DatetimeIndex` and :class:`TimedeltaIndex`. Use the associated ``.set_freq()`` method instead (:issue:`20886`) .. _whatsnew_0230.prior_deprecations: diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py index 158b272384ae8..d617f7e322f9f 100644 --- a/pandas/core/indexes/datetimelike.py +++ b/pandas/core/indexes/datetimelike.py @@ -236,12 +236,44 @@ def freq(self): @freq.setter def freq(self, value): + msg = ('Setting {obj}.freq has been deprecated and will be removed ' + 'in a future version; use {obj}.set_freq instead.' + ).format(obj=type(self).__name__) + warnings.warn(msg, FutureWarning, stacklevel=2) if value is not None: value = frequencies.to_offset(value) self._validate_frequency(self, value) self._freq = value + def set_freq(self, freq): + """ + Set the frequency of the DatetimeIndex or TimedeltaIndex to the + specified frequency `freq`. + + Parameters + ---------- + freq: str or Offset + The frequency to set on the DatetimeIndex or TimedeltaIndex + + Returns + ------- + new: DatetimeIndex or TimedeltaIndex with the new frequency + + Raises + ------ + ValueError + If the values of the DatetimeIndex or TimedeltaIndex are not + compatible with the new frequency + """ + if freq is not None: + freq = frequencies.to_offset(freq) + self._validate_frequency(self, freq) + + new = self.copy() + new._freq = freq + return new + class DatetimeIndexOpsMixin(object): """ common ops mixin to support a unified interface datetimelike Index """ diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index e9ab443a978f8..0078ef5744b65 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -250,6 +250,7 @@ class DatetimeIndex(DatelikeOps, TimelikeOps, DatetimeIndexOpsMixin, normalize strftime snap + set_freq tz_convert tz_localize round @@ -319,7 +320,7 @@ def _add_comparison_methods(cls): _other_ops = ['date', 'time'] _datetimelike_ops = _field_ops + _object_ops + _bool_ops + _other_ops _datetimelike_methods = ['to_period', 'tz_localize', - 'tz_convert', + 'tz_convert', 'set_freq', 'normalize', 'strftime', 'round', 'floor', 'ceil', 'month_name', 'day_name'] @@ -460,7 +461,7 @@ def __new__(cls, data=None, if freq_infer: inferred = subarr.inferred_freq if inferred: - subarr.freq = to_offset(inferred) + subarr._freq = to_offset(inferred) return subarr._deepcopy_if_needed(ref_to_data, copy) @@ -759,7 +760,7 @@ def _cached_range(cls, start=None, end=None, periods=None, freq=None, arr = tools.to_datetime(list(xdr), box=False) cachedRange = DatetimeIndex._simple_new(arr) - cachedRange.freq = freq + cachedRange._freq = freq cachedRange = cachedRange.tz_localize(None) cachedRange.name = None drc[freq] = cachedRange @@ -794,7 +795,7 @@ def _cached_range(cls, start=None, end=None, periods=None, freq=None, indexSlice = cachedRange[startLoc:endLoc] indexSlice.name = name - indexSlice.freq = freq + indexSlice._freq = freq return indexSlice @@ -1184,7 +1185,7 @@ def union(self, other): result._tz = timezones.tz_standardize(this.tz) if (result.freq is None and (this.freq is not None or other.freq is not None)): - result.freq = to_offset(result.inferred_freq) + result._freq = to_offset(result.inferred_freq) return result def to_perioddelta(self, freq): @@ -1232,7 +1233,7 @@ def union_many(self, others): this._tz = timezones.tz_standardize(tz) if this.freq is None: - this.freq = to_offset(this.inferred_freq) + this._freq = to_offset(this.inferred_freq) return this def join(self, other, how='left', level=None, return_indexers=False, @@ -1393,7 +1394,7 @@ def intersection(self, other): result = Index.intersection(self, other) if isinstance(result, DatetimeIndex): if result.freq is None: - result.freq = to_offset(result.inferred_freq) + result._freq = to_offset(result.inferred_freq) return result elif (other.freq is None or self.freq is None or @@ -1404,7 +1405,7 @@ def intersection(self, other): result = self._shallow_copy(result._values, name=result.name, tz=result.tz, freq=None) if result.freq is None: - result.freq = to_offset(result.inferred_freq) + result._freq = to_offset(result.inferred_freq) return result if len(self) == 0: @@ -1738,9 +1739,13 @@ def offset(self): def offset(self, value): """get/set the frequency of the Index""" msg = ('DatetimeIndex.offset has been deprecated and will be removed ' - 'in a future version; use DatetimeIndex.freq instead.') + 'in a future version; use DatetimeIndex.set_freq instead.') warnings.warn(msg, FutureWarning, stacklevel=2) - self.freq = value + if value is not None: + value = to_offset(value) + self._validate_frequency(self, value) + + self._freq = value year = _field_accessor('year', 'Y', "The year of the datetime") month = _field_accessor('month', 'M', diff --git a/pandas/core/indexes/timedeltas.py b/pandas/core/indexes/timedeltas.py index 6b278fc35c831..2e94a01c59049 100644 --- a/pandas/core/indexes/timedeltas.py +++ b/pandas/core/indexes/timedeltas.py @@ -149,6 +149,7 @@ class TimedeltaIndex(DatetimeIndexOpsMixin, TimelikeOps, Int64Index): Methods ------- + set_freq to_pytimedelta to_series round @@ -177,7 +178,7 @@ def _join_i8_wrapper(joinf, **kwargs): _field_ops = ['days', 'seconds', 'microseconds', 'nanoseconds'] _datetimelike_ops = _field_ops + _object_ops + _bool_ops _datetimelike_methods = ["to_pytimedelta", "total_seconds", - "round", "floor", "ceil"] + "round", "floor", "ceil", "set_freq"] @classmethod def _add_comparison_methods(cls): @@ -253,14 +254,14 @@ def __new__(cls, data=None, unit=None, freq=None, start=None, end=None, if freq is not None and not freq_infer: index = cls._simple_new(data, name=name) cls._validate_frequency(index, freq) - index.freq = freq + index._freq = freq return index if freq_infer: index = cls._simple_new(data, name=name) inferred = index.inferred_freq if inferred: - index.freq = to_offset(inferred) + index._freq = to_offset(inferred) return index return cls._simple_new(data, name=name, freq=freq) @@ -598,7 +599,7 @@ def union(self, other): result = Index.union(this, other) if isinstance(result, TimedeltaIndex): if result.freq is None: - result.freq = to_offset(result.inferred_freq) + result._freq = to_offset(result.inferred_freq) return result def join(self, other, how='left', level=None, return_indexers=False, diff --git a/pandas/core/resample.py b/pandas/core/resample.py index 0707cc756682e..6be85046490db 100644 --- a/pandas/core/resample.py +++ b/pandas/core/resample.py @@ -904,7 +904,7 @@ def _downsample(self, how, **kwargs): if not len(ax): # reset to the new freq obj = obj.copy() - obj.index.freq = self.freq + obj.index = obj.index.set_freq(self.freq) return obj # do we have a regular frequency diff --git a/pandas/tests/categorical/test_constructors.py b/pandas/tests/categorical/test_constructors.py index 6cc34770a65e0..2dcc7b0159738 100644 --- a/pandas/tests/categorical/test_constructors.py +++ b/pandas/tests/categorical/test_constructors.py @@ -256,36 +256,31 @@ def test_constructor_with_generator(self): cat = Categorical([0, 1, 2], categories=xrange(3)) tm.assert_categorical_equal(cat, exp) - def test_constructor_with_datetimelike(self): - + @pytest.mark.parametrize('dtl', [ + date_range('1995-01-01', periods=5, freq='s'), + date_range('1995-01-01', periods=5, freq='s', tz='US/Eastern'), + timedelta_range('1 day', periods=5, freq='s')]) + def test_constructor_with_datetimelike(self, dtl): # 12077 # constructor wwth a datetimelike and NaT + s = Series(dtl) + c = Categorical(s) + expected = dtl._constructor(s).set_freq(None) + tm.assert_index_equal(c.categories, expected) + tm.assert_numpy_array_equal(c.codes, np.arange(5, dtype='int8')) + + # with NaT + s2 = s.copy() + s2.iloc[-1] = NaT + c = Categorical(s2) + expected = dtl._constructor(s2.dropna()).set_freq(None) + tm.assert_index_equal(c.categories, expected) + + exp = np.array([0, 1, 2, 3, -1], dtype=np.int8) + tm.assert_numpy_array_equal(c.codes, exp) - for dtl in [date_range('1995-01-01 00:00:00', periods=5, freq='s'), - date_range('1995-01-01 00:00:00', periods=5, - freq='s', tz='US/Eastern'), - timedelta_range('1 day', periods=5, freq='s')]: - - s = Series(dtl) - c = Categorical(s) - expected = type(dtl)(s) - expected.freq = None - tm.assert_index_equal(c.categories, expected) - tm.assert_numpy_array_equal(c.codes, np.arange(5, dtype='int8')) - - # with NaT - s2 = s.copy() - s2.iloc[-1] = NaT - c = Categorical(s2) - expected = type(dtl)(s2.dropna()) - expected.freq = None - tm.assert_index_equal(c.categories, expected) - - exp = np.array([0, 1, 2, 3, -1], dtype=np.int8) - tm.assert_numpy_array_equal(c.codes, exp) - - result = repr(c) - assert 'NaT' in result + result = repr(c) + assert 'NaT' in result def test_constructor_from_index_series_datetimetz(self): idx = date_range('2015-01-01 10:00', freq='D', periods=3, diff --git a/pandas/tests/indexes/datetimelike.py b/pandas/tests/indexes/datetimelike.py index e32e18ea0ec4a..0268687df5958 100644 --- a/pandas/tests/indexes/datetimelike.py +++ b/pandas/tests/indexes/datetimelike.py @@ -67,7 +67,7 @@ def test_map_dictlike(self, mapper): # don't compare the freqs if isinstance(expected, pd.DatetimeIndex): - expected.freq = None + expected = expected.set_freq(None) result = self.index.map(mapper(expected, self.index)) tm.assert_index_equal(result, expected) @@ -88,3 +88,15 @@ def test_asobject_deprecated(self): with tm.assert_produces_warning(FutureWarning): i = d.asobject assert isinstance(i, pd.Index) + + def test_freq_setter_deprecated(self): + # GH 20678/20886 + idx = self.create_index() + + # no warning for getter + with tm.assert_produces_warning(None): + idx.freq + + # warning for setter + with tm.assert_produces_warning(FutureWarning): + idx.freq = pd.offsets.Day() diff --git a/pandas/tests/indexes/datetimes/test_date_range.py b/pandas/tests/indexes/datetimes/test_date_range.py index bbe9cb65eb1a9..40b8e957d3644 100644 --- a/pandas/tests/indexes/datetimes/test_date_range.py +++ b/pandas/tests/indexes/datetimes/test_date_range.py @@ -396,6 +396,7 @@ def test_misc(self): assert len(dr) == 20 assert dr[0] == firstDate assert dr[-1] == end + assert dr.freq == BDay() def test_date_parse_failure(self): badly_formed_date = '2007/100/1' @@ -416,7 +417,6 @@ def test_daterange_bug_456(self): # GH #456 rng1 = bdate_range('12/5/2011', '12/5/2011') rng2 = bdate_range('12/2/2011', '12/5/2011') - rng2.freq = BDay() result = rng1.union(rng2) assert isinstance(result, DatetimeIndex) @@ -658,12 +658,12 @@ def test_misc(self): assert len(dr) == 20 assert dr[0] == firstDate assert dr[-1] == end + assert dr.freq == CDay() def test_daterange_bug_456(self): # GH #456 rng1 = bdate_range('12/5/2011', '12/5/2011', freq='C') rng2 = bdate_range('12/2/2011', '12/5/2011', freq='C') - rng2.freq = CDay() result = rng1.union(rng2) assert isinstance(result, DatetimeIndex) diff --git a/pandas/tests/indexes/datetimes/test_ops.py b/pandas/tests/indexes/datetimes/test_ops.py index c6334e70a1d2c..ae6d5044044e2 100644 --- a/pandas/tests/indexes/datetimes/test_ops.py +++ b/pandas/tests/indexes/datetimes/test_ops.py @@ -406,37 +406,75 @@ def test_equals(self): assert not idx.equals(list(idx3)) assert not idx.equals(pd.Series(idx3)) + @pytest.mark.parametrize('values', [ + ['20180101', '20180103', '20180105'], []]) + @pytest.mark.parametrize('freq', [ + '2D', Day(2), '2B', BDay(2), '48H', Hour(48)]) + @pytest.mark.parametrize('tz', [None, 'US/Eastern']) + def test_set_freq(self, values, freq, tz): + # GH 20886 + idx = DatetimeIndex(values, tz=tz) + + # can set to an offset, converting from string if necessary + idx = idx.set_freq(freq) + assert idx.freq == freq + assert isinstance(idx.freq, ABCDateOffset) + + # can reset to None + idx = idx.set_freq(None) + assert idx.freq is None + + def test_set_freq_errors(self): + # GH 20886 + idx = DatetimeIndex(['20180101', '20180103', '20180105']) + + # setting with an incompatible freq + msg = ('Inferred frequency 2D from passed values does not conform to ' + 'passed frequency 5D') + with tm.assert_raises_regex(ValueError, msg): + idx.set_freq('5D') + + # setting with non-freq string + with tm.assert_raises_regex(ValueError, 'Invalid frequency'): + idx.set_freq('foo') + @pytest.mark.parametrize('values', [ ['20180101', '20180103', '20180105'], []]) @pytest.mark.parametrize('freq', [ '2D', Day(2), '2B', BDay(2), '48H', Hour(48)]) @pytest.mark.parametrize('tz', [None, 'US/Eastern']) def test_freq_setter(self, values, freq, tz): - # GH 20678 + # GH 20678/20886 idx = DatetimeIndex(values, tz=tz) # can set to an offset, converting from string if necessary - idx.freq = freq + with tm.assert_produces_warning(FutureWarning): + idx.freq = freq + assert idx.freq == freq assert isinstance(idx.freq, ABCDateOffset) # can reset to None - idx.freq = None + with tm.assert_produces_warning(FutureWarning): + idx.freq = None + assert idx.freq is None def test_freq_setter_errors(self): - # GH 20678 + # GH 20678/20886 idx = DatetimeIndex(['20180101', '20180103', '20180105']) # setting with an incompatible freq msg = ('Inferred frequency 2D from passed values does not conform to ' 'passed frequency 5D') with tm.assert_raises_regex(ValueError, msg): - idx.freq = '5D' + with tm.assert_produces_warning(FutureWarning): + idx.freq = '5D' # setting with non-freq string with tm.assert_raises_regex(ValueError, 'Invalid frequency'): - idx.freq = 'foo' + with tm.assert_produces_warning(FutureWarning): + idx.freq = 'foo' def test_offset_deprecated(self): # GH 20716 diff --git a/pandas/tests/indexes/datetimes/test_setops.py b/pandas/tests/indexes/datetimes/test_setops.py index cb9364edc0cc3..6f99a286787aa 100644 --- a/pandas/tests/indexes/datetimes/test_setops.py +++ b/pandas/tests/indexes/datetimes/test_setops.py @@ -91,9 +91,7 @@ def test_union_bug_4564(self): def test_union_freq_both_none(self): # GH11086 - expected = bdate_range('20150101', periods=10) - expected.freq = None - + expected = bdate_range('20150101', periods=10).set_freq(None) result = expected.union(expected) tm.assert_index_equal(result, expected) assert result.freq is None diff --git a/pandas/tests/indexes/period/test_ops.py b/pandas/tests/indexes/period/test_ops.py index 85aa3f6a38fb3..7d117b0b626cf 100644 --- a/pandas/tests/indexes/period/test_ops.py +++ b/pandas/tests/indexes/period/test_ops.py @@ -401,18 +401,6 @@ def test_equals(self, freq): assert not idx.equals(list(idx3)) assert not idx.equals(pd.Series(idx3)) - def test_freq_setter_deprecated(self): - # GH 20678 - idx = pd.period_range('2018Q1', periods=4, freq='Q') - - # no warning for getter - with tm.assert_produces_warning(None): - idx.freq - - # warning for setter - with tm.assert_produces_warning(FutureWarning): - idx.freq = pd.offsets.Day() - class TestPeriodIndexSeriesMethods(object): """ Test PeriodIndex and Period Series Ops consistency """ diff --git a/pandas/tests/indexes/timedeltas/test_ops.py b/pandas/tests/indexes/timedeltas/test_ops.py index 2e257bb8a500a..1c71b033905c8 100644 --- a/pandas/tests/indexes/timedeltas/test_ops.py +++ b/pandas/tests/indexes/timedeltas/test_ops.py @@ -308,39 +308,80 @@ def test_equals(self): assert not idx.equals(list(idx2)) assert not idx.equals(pd.Series(idx2)) + @pytest.mark.parametrize('values', [['0 days', '2 days', '4 days'], []]) + @pytest.mark.parametrize('freq', ['2D', Day(2), '48H', Hour(48)]) + def test_set_freq(self, values, freq): + # GH 20886 + idx = TimedeltaIndex(values) + + # can set to an offset, converting from string if necessary + idx = idx.set_freq(freq) + assert idx.freq == freq + assert isinstance(idx.freq, ABCDateOffset) + + # can reset to None + idx = idx.set_freq(None) + assert idx.freq is None + + def test_set_freq_errors(self): + # GH 20886 + idx = TimedeltaIndex(['0 days', '2 days', '4 days']) + + # setting with an incompatible freq + msg = ('Inferred frequency 2D from passed values does not conform to ' + 'passed frequency 5D') + with tm.assert_raises_regex(ValueError, msg): + idx.set_freq('5D') + + # setting with a non-fixed frequency + msg = '<2 \* BusinessDays> is a non-fixed frequency' + with tm.assert_raises_regex(ValueError, msg): + idx.set_freq('2B') + + # setting with non-freq string + with tm.assert_raises_regex(ValueError, 'Invalid frequency'): + idx.set_freq('foo') + @pytest.mark.parametrize('values', [['0 days', '2 days', '4 days'], []]) @pytest.mark.parametrize('freq', ['2D', Day(2), '48H', Hour(48)]) def test_freq_setter(self, values, freq): - # GH 20678 + # GH 20678/20886 idx = TimedeltaIndex(values) # can set to an offset, converting from string if necessary - idx.freq = freq + with tm.assert_produces_warning(FutureWarning): + idx.freq = freq + assert idx.freq == freq assert isinstance(idx.freq, ABCDateOffset) # can reset to None - idx.freq = None + with tm.assert_produces_warning(FutureWarning): + idx.freq = None + assert idx.freq is None def test_freq_setter_errors(self): - # GH 20678 + # GH 20678/20886 idx = TimedeltaIndex(['0 days', '2 days', '4 days']) # setting with an incompatible freq msg = ('Inferred frequency 2D from passed values does not conform to ' 'passed frequency 5D') with tm.assert_raises_regex(ValueError, msg): - idx.freq = '5D' + with tm.assert_produces_warning(FutureWarning): + idx.freq = '5D' # setting with a non-fixed frequency msg = '<2 \* BusinessDays> is a non-fixed frequency' with tm.assert_raises_regex(ValueError, msg): - idx.freq = '2B' + with tm.assert_produces_warning(FutureWarning): + idx.freq = '2B' # setting with non-freq string with tm.assert_raises_regex(ValueError, 'Invalid frequency'): - idx.freq = 'foo' + with tm.assert_produces_warning(FutureWarning): + idx.freq = 'foo' class TestTimedeltas(object): diff --git a/pandas/tests/series/test_api.py b/pandas/tests/series/test_api.py index f7f1ea019a3f0..9fd9a1eea1f3d 100644 --- a/pandas/tests/series/test_api.py +++ b/pandas/tests/series/test_api.py @@ -705,6 +705,7 @@ def test_dt_accessor_api_for_categorical(self): ('floor', ("D",), {}), ('ceil', ("D",), {}), ('asfreq', ("D",), {}), + ('set_freq', ("24H",), {}), # ('tz_localize', ("UTC",), {}), ] _special_func_names = [f[0] for f in special_func_defs] diff --git a/pandas/tests/series/test_datetime_values.py b/pandas/tests/series/test_datetime_values.py index 47798d0ddd7f5..cd4a88176c0fb 100644 --- a/pandas/tests/series/test_datetime_values.py +++ b/pandas/tests/series/test_datetime_values.py @@ -34,10 +34,11 @@ def test_dt_namespace_accessor(self): ok_for_dt = DatetimeIndex._datetimelike_ops ok_for_dt_methods = ['to_period', 'to_pydatetime', 'tz_localize', 'tz_convert', 'normalize', 'strftime', 'round', - 'floor', 'ceil', 'day_name', 'month_name'] + 'floor', 'ceil', 'day_name', 'month_name', + 'set_freq'] ok_for_td = TimedeltaIndex._datetimelike_ops ok_for_td_methods = ['components', 'to_pytimedelta', 'total_seconds', - 'round', 'floor', 'ceil'] + 'round', 'floor', 'ceil', 'set_freq'] def get_expected(s, name): result = getattr(Index(s._values), prop) @@ -460,3 +461,38 @@ def test_datetime_understood(self): expected = pd.Series(pd.to_datetime([ '2011-12-26', '2011-12-27', '2011-12-28'])) tm.assert_series_equal(result, expected) + + @pytest.mark.xfail(reason='GH 20937') + @pytest.mark.parametrize('data, new_freq', [ + (date_range('20180101', periods=3), 'B'), + (date_range('20180101', periods=3, tz='US/Eastern'), 'B'), + (timedelta_range('1 day', periods=3), '86400S')]) + def test_set_freq(self, data, new_freq): + # GH 20886 + s = Series(data) + + # can set to alternate freq + result = s.dt.set_freq(new_freq) + assert result.dt.freq == new_freq + + # can reset to None + result = s.dt.set_freq(None) + assert result.dt.freq is None + + @pytest.mark.parametrize('data', [ + date_range('20180101', periods=3), + date_range('20180101', periods=3, tz='US/Eastern'), + timedelta_range('1 day', periods=3)]) + def test_set_freq_errors(self, data): + # GH 20886 + s = Series(data) + + # setting with an incompatible freq + msg = ('Inferred frequency D from passed values does not conform to ' + 'passed frequency 5D') + with tm.assert_raises_regex(ValueError, msg): + s.dt.set_freq('5D') + + # setting with non-freq string + with tm.assert_raises_regex(ValueError, 'Invalid frequency'): + s.dt.set_freq('foo') diff --git a/pandas/tests/test_resample.py b/pandas/tests/test_resample.py index c1257cce9a9a4..f0aad60a0e4b5 100644 --- a/pandas/tests/test_resample.py +++ b/pandas/tests/test_resample.py @@ -22,7 +22,6 @@ from pandas.core.groupby.groupby import DataError import pandas.core.common as com -from pandas.tseries.frequencies import to_offset from pandas.core.indexes.datetimes import date_range from pandas.tseries.offsets import Minute, BDay from pandas.core.indexes.period import period_range, PeriodIndex, Period @@ -624,7 +623,7 @@ def test_asfreq(self, series_and_frame, freq): result = obj.resample(freq).asfreq() if freq == '2D': new_index = obj.index.take(np.arange(0, len(obj.index), 2)) - new_index.freq = to_offset('2D') + new_index = new_index.set_freq('2D') else: new_index = self.create_index(obj.index[0], obj.index[-1], freq=freq)