Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DEPR: setting DTI.freq, DTI.offset, DTI.asobject #29801

Merged
merged 6 commits into from
Nov 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/source/whatsnew/v1.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,9 @@ or ``matplotlib.Axes.plot``. See :ref:`plotting.formatters` for more.
- Removed the previously deprecated :meth:`DataFrame.get_ftype_counts`, :meth:`Series.get_ftype_counts` (:issue:`18243`)
- Removed the previously deprecated :meth:`Index.get_duplicated`, use ``idx[idx.duplicated()].unique()`` instead (:issue:`20239`)
- Removed the previously deprecated :meth:`Series.clip_upper`, :meth:`Series.clip_lower`, :meth:`DataFrame.clip_upper`, :meth:`DataFrame.clip_lower` (:issue:`24203`)
- Removed the ability to alter :attr:`DatetimeIndex.freq`, :attr:`TimedeltaIndex.freq`, or :attr:`PeriodIndex.freq` (:issue:`20772`)
- Removed the previously deprecated :attr:`DatetimeIndex.offset` (:issue:`20730`)
- Removed the previously deprecated :meth:`DatetimeIndex.asobject`, :meth:`TimedeltaIndex.asobject`, :meth:`PeriodIndex.asobject`, use ``astype(object)`` instead (:issue:`29801`)
- Removed previously deprecated "order" argument from :func:`factorize` (:issue:`19751`)
- Removed previously deprecated "v" argument from :meth:`FrozenNDarray.searchsorted`, use "value" instead (:issue:`22672`)
- :func:`read_stata` and :meth:`DataFrame.to_stata` no longer supports the "encoding" argument (:issue:`21400`)
Expand Down
33 changes: 7 additions & 26 deletions pandas/core/indexes/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"""
import operator
from typing import Set
import warnings

import numpy as np

Expand Down Expand Up @@ -104,11 +103,6 @@ def freq(self):
"""
return self._data.freq

@freq.setter
def freq(self, value):
# validation is handled by _data setter
self._data.freq = value

@property
def freqstr(self):
"""
Expand Down Expand Up @@ -332,23 +326,6 @@ def take(self, indices, axis=0, allow_fill=True, fill_value=None, **kwargs):
_na_value = NaT
"""The expected NA value to use with this index."""

@property
def asobject(self):
"""
Return object Index which contains boxed values.

.. deprecated:: 0.23.0
Use ``astype(object)`` instead.

*this is an internal non-public method*
"""
warnings.warn(
"'asobject' is deprecated. Use 'astype(object)' instead",
FutureWarning,
stacklevel=2,
)
return self.astype(object)

def _convert_tolerance(self, tolerance, target):
tolerance = np.asarray(to_timedelta(tolerance).to_numpy())

Expand Down Expand Up @@ -612,7 +589,8 @@ def intersection(self, other, sort=False):
result = Index.intersection(self, other, sort=sort)
if isinstance(result, type(self)):
if result.freq is None:
result.freq = to_offset(result.inferred_freq)
# TODO: find a less code-smelly way to set this
result._data._freq = to_offset(result.inferred_freq)
return result

elif (
Expand All @@ -626,15 +604,18 @@ def intersection(self, other, sort=False):

# Invalidate the freq of `result`, which may not be correct at
# this point, depending on the values.
result.freq = None

# TODO: find a less code-smelly way to set this
result._data._freq = None
if hasattr(self, "tz"):
result = self._shallow_copy(
result._values, name=result.name, tz=result.tz, freq=None
)
else:
result = self._shallow_copy(result._values, name=result.name, freq=None)
if result.freq is None:
result.freq = to_offset(result.inferred_freq)
# TODO: find a less code-smelly way to set this
result._data._freq = to_offset(result.inferred_freq)
return result

# to make our life easier, "sort" the two ranges
Expand Down
6 changes: 3 additions & 3 deletions pandas/core/indexes/datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ def _convert_for_op(self, value):
@Appender(Index.difference.__doc__)
def difference(self, other, sort=None):
new_idx = super().difference(other, sort=sort)
new_idx.freq = None
new_idx._data._freq = None
return new_idx

# --------------------------------------------------------------------
Expand Down Expand Up @@ -522,7 +522,7 @@ def _union(self, other, sort):
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._data._freq = to_offset(result.inferred_freq)
return result

def union_many(self, others):
Expand Down Expand Up @@ -1208,7 +1208,7 @@ def offset(self, value):
)
)
warnings.warn(msg, FutureWarning, stacklevel=2)
self.freq = value
self._data.freq = value

def __getitem__(self, key):
result = self._data.__getitem__(key)
Expand Down
15 changes: 0 additions & 15 deletions pandas/core/indexes/period.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,21 +313,6 @@ def values(self):
def freq(self) -> DateOffset:
return self._data.freq

@freq.setter
def freq(self, value):
value = Period._maybe_convert_freq(value)
# TODO: When this deprecation is enforced, PeriodIndex.freq can
# be removed entirely, and we'll just inherit.
msg = (
"Setting {cls}.freq has been deprecated and will be "
"removed in a future version; use {cls}.asfreq instead. "
"The {cls}.freq setter is not guaranteed to work."
)
warnings.warn(msg.format(cls=type(self).__name__), FutureWarning, stacklevel=2)
# PeriodArray._freq isn't actually mutable. We set the private _freq
# here, but people shouldn't be doing this anyway.
self._data._freq = value

def _shallow_copy(self, values=None, **kwargs):
# TODO: simplify, figure out type of values
if values is None:
Expand Down
6 changes: 4 additions & 2 deletions pandas/core/indexes/timedeltas.py
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,8 @@ def _union(self, other, sort):
result = Index._union(this, other, sort=sort)
if isinstance(result, TimedeltaIndex):
if result.freq is None:
result.freq = to_offset(result.inferred_freq)
# TODO: find a less code-smelly way to set this
result._data._freq = to_offset(result.inferred_freq)
return result

def join(self, other, how="left", level=None, return_indexers=False, sort=False):
Expand Down Expand Up @@ -409,7 +410,8 @@ def intersection(self, other, sort=False):
@Appender(Index.difference.__doc__)
def difference(self, other, sort=None):
new_idx = super().difference(other, sort=sort)
new_idx.freq = None
# TODO: find a less code-smelly way to set this
new_idx._data._freq = None
return new_idx

def _wrap_joined_index(self, joined, other):
Expand Down
3 changes: 2 additions & 1 deletion pandas/core/resample.py
Original file line number Diff line number Diff line change
Expand Up @@ -1080,7 +1080,8 @@ def _downsample(self, how, **kwargs):
if not len(ax):
# reset to the new freq
obj = obj.copy()
obj.index.freq = self.freq
# TODO: find a less code-smelly way to set this
obj.index._data._freq = self.freq
return obj

# do we have a regular frequency
Expand Down
4 changes: 2 additions & 2 deletions pandas/tests/arrays/categorical/test_constructors.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ def test_constructor_with_datetimelike(self, dtl):
c = Categorical(s)

expected = type(dtl)(s)
expected.freq = None
expected._data.freq = None

tm.assert_index_equal(c.categories, expected)
tm.assert_numpy_array_equal(c.codes, np.arange(5, dtype="int8"))
Expand All @@ -322,7 +322,7 @@ def test_constructor_with_datetimelike(self, dtl):
c = Categorical(s2)

expected = type(dtl)(s2.dropna())
expected.freq = None
expected._data.freq = None

tm.assert_index_equal(c.categories, expected)

Expand Down
9 changes: 1 addition & 8 deletions pandas/tests/indexes/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def test_map_dictlike(self, mapper):

# don't compare the freqs
if isinstance(expected, pd.DatetimeIndex):
expected.freq = None
expected._data.freq = None

result = index.map(mapper(expected, index))
tm.assert_index_equal(result, expected)
Expand All @@ -95,10 +95,3 @@ def test_map_dictlike(self, mapper):
expected = pd.Index([np.nan] * len(index))
result = index.map(mapper([], []))
tm.assert_index_equal(result, expected)

def test_asobject_deprecated(self):
# GH18572
d = self.create_index()
with tm.assert_produces_warning(FutureWarning):
i = d.asobject
assert isinstance(i, pd.Index)
4 changes: 2 additions & 2 deletions pandas/tests/indexes/datetimes/test_date_range.py
Original file line number Diff line number Diff line change
Expand Up @@ -798,7 +798,7 @@ 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()
rng2._data.freq = BDay() # TODO: shouldnt this already be set?

result = rng1.union(rng2)
assert isinstance(result, DatetimeIndex)
Expand Down Expand Up @@ -855,7 +855,7 @@ 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()
rng2._data.freq = CDay() # TODO: shouldnt this already be set?

result = rng1.union(rng2)
assert isinstance(result, DatetimeIndex)
Expand Down
8 changes: 4 additions & 4 deletions pandas/tests/indexes/datetimes/test_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -413,12 +413,12 @@ def test_freq_setter(self, values, freq, tz):
idx = DatetimeIndex(values, tz=tz)

# can set to an offset, converting from string if necessary
idx.freq = freq
idx._data.freq = freq
assert idx.freq == freq
assert isinstance(idx.freq, ABCDateOffset)

# can reset to None
idx.freq = None
idx._data.freq = None
assert idx.freq is None

def test_freq_setter_errors(self):
Expand All @@ -431,11 +431,11 @@ def test_freq_setter_errors(self):
"passed frequency 5D"
)
with pytest.raises(ValueError, match=msg):
idx.freq = "5D"
idx._data.freq = "5D"

# setting with non-freq string
with pytest.raises(ValueError, match="Invalid frequency"):
idx.freq = "foo"
idx._data.freq = "foo"

def test_offset_deprecated(self):
# GH 20716
Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/indexes/datetimes/test_setops.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ def test_union_bug_4564(self, sort):
def test_union_freq_both_none(self, sort):
# GH11086
expected = bdate_range("20150101", periods=10)
expected.freq = None
expected._data.freq = None

result = expected.union(expected, sort=sort)
tm.assert_index_equal(result, expected)
Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/indexes/period/test_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,5 +343,5 @@ def test_freq_setter_deprecated(self):
idx.freq

# warning for setter
with tm.assert_produces_warning(FutureWarning):
with pytest.raises(AttributeError, match="can't set attribute"):
idx.freq = pd.offsets.Day()
10 changes: 5 additions & 5 deletions pandas/tests/indexes/timedeltas/test_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,12 +286,12 @@ def test_freq_setter(self, values, freq):
idx = TimedeltaIndex(values)

# can set to an offset, converting from string if necessary
idx.freq = freq
idx._data.freq = freq
assert idx.freq == freq
assert isinstance(idx.freq, ABCDateOffset)

# can reset to None
idx.freq = None
idx._data.freq = None
assert idx.freq is None

def test_freq_setter_errors(self):
Expand All @@ -304,13 +304,13 @@ def test_freq_setter_errors(self):
"passed frequency 5D"
)
with pytest.raises(ValueError, match=msg):
idx.freq = "5D"
idx._data.freq = "5D"

# setting with a non-fixed frequency
msg = r"<2 \* BusinessDays> is a non-fixed frequency"
with pytest.raises(ValueError, match=msg):
idx.freq = "2B"
idx._data.freq = "2B"

# setting with non-freq string
with pytest.raises(ValueError, match="Invalid frequency"):
idx.freq = "foo"
idx._data.freq = "foo"
2 changes: 1 addition & 1 deletion pandas/tests/reshape/test_concat.py
Original file line number Diff line number Diff line change
Expand Up @@ -2774,5 +2774,5 @@ def test_concat_datetimeindex_freq():
# Non-monotonic index result
result = pd.concat([expected[50:], expected[:50]])
expected = pd.DataFrame(data[50:] + data[:50], index=dr[50:].append(dr[:50]))
expected.index.freq = None
expected.index._data.freq = None
tm.assert_frame_equal(result, expected)