Skip to content

Commit

Permalink
DEPR offsets: rename ‘Y’ to ‘YE' (#55792)
Browse files Browse the repository at this point in the history
  • Loading branch information
natmokval authored Nov 9, 2023
1 parent 95561fc commit 7e0d36f
Show file tree
Hide file tree
Showing 44 changed files with 237 additions and 169 deletions.
30 changes: 15 additions & 15 deletions doc/source/user_guide/timeseries.rst
Original file line number Diff line number Diff line change
Expand Up @@ -889,7 +889,7 @@ into ``freq`` keyword arguments. The available date offsets and associated frequ
:class:`~pandas.tseries.offsets.BQuarterEnd`, ``'BQ``, "business quarter end"
:class:`~pandas.tseries.offsets.BQuarterBegin`, ``'BQS'``, "business quarter begin"
:class:`~pandas.tseries.offsets.FY5253Quarter`, ``'REQ'``, "retail (aka 52-53 week) quarter"
:class:`~pandas.tseries.offsets.YearEnd`, ``'Y'``, "calendar year end"
:class:`~pandas.tseries.offsets.YearEnd`, ``'YE'``, "calendar year end"
:class:`~pandas.tseries.offsets.YearBegin`, ``'YS'`` or ``'BYS'``,"calendar year begin"
:class:`~pandas.tseries.offsets.BYearEnd`, ``'BY'``, "business year end"
:class:`~pandas.tseries.offsets.BYearBegin`, ``'BYS'``, "business year begin"
Expand Down Expand Up @@ -1252,7 +1252,7 @@ frequencies. We will refer to these aliases as *offset aliases*.
"BQ", "business quarter end frequency"
"QS", "quarter start frequency"
"BQS", "business quarter start frequency"
"Y", "year end frequency"
"YE", "year end frequency"
"BY", "business year end frequency"
"YS", "year start frequency"
"BYS", "business year start frequency"
Expand Down Expand Up @@ -1379,18 +1379,18 @@ For some frequencies you can specify an anchoring suffix:
"(B)Q(E)(S)\-SEP", "quarterly frequency, year ends in September"
"(B)Q(E)(S)\-OCT", "quarterly frequency, year ends in October"
"(B)Q(E)(S)\-NOV", "quarterly frequency, year ends in November"
"(B)Y(S)\-DEC", "annual frequency, anchored end of December. Same as 'Y'"
"(B)Y(S)\-JAN", "annual frequency, anchored end of January"
"(B)Y(S)\-FEB", "annual frequency, anchored end of February"
"(B)Y(S)\-MAR", "annual frequency, anchored end of March"
"(B)Y(S)\-APR", "annual frequency, anchored end of April"
"(B)Y(S)\-MAY", "annual frequency, anchored end of May"
"(B)Y(S)\-JUN", "annual frequency, anchored end of June"
"(B)Y(S)\-JUL", "annual frequency, anchored end of July"
"(B)Y(S)\-AUG", "annual frequency, anchored end of August"
"(B)Y(S)\-SEP", "annual frequency, anchored end of September"
"(B)Y(S)\-OCT", "annual frequency, anchored end of October"
"(B)Y(S)\-NOV", "annual frequency, anchored end of November"
"(B)Y(E)(S)\-DEC", "annual frequency, anchored end of December. Same as 'YE'"
"(B)Y(E)(S)\-JAN", "annual frequency, anchored end of January"
"(B)Y(E)(S)\-FEB", "annual frequency, anchored end of February"
"(B)Y(E)(S)\-MAR", "annual frequency, anchored end of March"
"(B)Y(E)(S)\-APR", "annual frequency, anchored end of April"
"(B)Y(E)(S)\-MAY", "annual frequency, anchored end of May"
"(B)Y(E)(S)\-JUN", "annual frequency, anchored end of June"
"(B)Y(E)(S)\-JUL", "annual frequency, anchored end of July"
"(B)Y(E)(S)\-AUG", "annual frequency, anchored end of August"
"(B)Y(E)(S)\-SEP", "annual frequency, anchored end of September"
"(B)Y(E)(S)\-OCT", "annual frequency, anchored end of October"
"(B)Y(E)(S)\-NOV", "annual frequency, anchored end of November"

These can be used as arguments to ``date_range``, ``bdate_range``, constructors
for ``DatetimeIndex``, as well as various other timeseries-related functions
Expand Down Expand Up @@ -1686,7 +1686,7 @@ the end of the interval.
.. warning::

The default values for ``label`` and ``closed`` is '**left**' for all
frequency offsets except for 'ME', 'Y', 'QE', 'BME', 'BY', 'BQ', and 'W'
frequency offsets except for 'ME', 'YE', 'QE', 'BME', 'BY', 'BQ', and 'W'
which all have a default of 'right'.

This might unintendedly lead to looking ahead, where the value for a later
Expand Down
27 changes: 6 additions & 21 deletions doc/source/whatsnew/v2.2.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -232,29 +232,14 @@ Other API changes
Deprecations
~~~~~~~~~~~~

Deprecate aliases ``M`` and ``Q`` in favour of ``ME`` and ``QE`` for offsets
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Deprecate aliases ``M``, ``Q``, and ``Y`` in favour of ``ME``, ``QE``, and ``YE`` for offsets
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The alias ``M`` is deprecated in favour of ``ME`` for offsets, please use ``ME`` for "month end" instead of ``M`` (:issue:`9586`)
Deprecated the following frequency aliases (:issue:`9586`):

For example:

*Previous behavior*:

.. code-block:: ipython
In [7]: pd.date_range('2020-01-01', periods=3, freq='M')
Out [7]:
DatetimeIndex(['2020-01-31', '2020-02-29', '2020-03-31'],
dtype='datetime64[ns]', freq='M')
*Future behavior*:

.. ipython:: python
pd.date_range('2020-01-01', periods=3, freq='ME')
The alias ``Q`` is deprecated in favour of ``QE`` for offsets, please use ``QE`` for "quarter end" instead of ``Q`` (:issue:`9586`)
- ``M`` (month end) has been renamed ``ME`` for offsets
- ``Q`` (quarter end) has been renamed ``QE`` for offsets
- ``Y`` (year end) has been renamed ``YE`` for offsets

For example:

Expand Down
39 changes: 39 additions & 0 deletions pandas/_libs/tslibs/dtypes.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,19 @@ OFFSET_TO_PERIOD_FREQSTR: dict = {
"QE-SEP": "Q-SEP",
"QE-OCT": "Q-OCT",
"QE-NOV": "Q-NOV",
"YE": "Y",
"YE-DEC": "Y-DEC",
"YE-JAN": "Y-JAN",
"YE-FEB": "Y-FEB",
"YE-MAR": "Y-MAR",
"YE-APR": "Y-APR",
"YE-MAY": "Y-MAY",
"YE-JUN": "Y-JUN",
"YE-JUL": "Y-JUL",
"YE-AUG": "Y-AUG",
"YE-SEP": "Y-SEP",
"YE-OCT": "Y-OCT",
"YE-NOV": "Y-NOV",
"W": "W",
"ME": "M",
"Y": "Y",
Expand All @@ -236,6 +249,32 @@ OFFSET_DEPR_FREQSTR: dict[str, str]= {
"Q-SEP": "QE-SEP",
"Q-OCT": "QE-OCT",
"Q-NOV": "QE-NOV",
"Y": "YE",
"Y-DEC": "YE-DEC",
"Y-JAN": "YE-JAN",
"Y-FEB": "YE-FEB",
"Y-MAR": "YE-MAR",
"Y-APR": "YE-APR",
"Y-MAY": "YE-MAY",
"Y-JUN": "YE-JUN",
"Y-JUL": "YE-JUL",
"Y-AUG": "YE-AUG",
"Y-SEP": "YE-SEP",
"Y-OCT": "YE-OCT",
"Y-NOV": "YE-NOV",
"A": "YE",
"A-DEC": "YE-DEC",
"A-JAN": "YE-JAN",
"A-FEB": "YE-FEB",
"A-MAR": "YE-MAR",
"A-APR": "YE-APR",
"A-MAY": "YE-MAY",
"A-JUN": "YE-JUN",
"A-JUL": "YE-JUL",
"A-AUG": "YE-AUG",
"A-SEP": "YE-SEP",
"A-OCT": "YE-OCT",
"A-NOV": "YE-NOV",
}
cdef dict c_OFFSET_TO_PERIOD_FREQSTR = OFFSET_TO_PERIOD_FREQSTR
cdef dict c_OFFSET_DEPR_FREQSTR = OFFSET_DEPR_FREQSTR
Expand Down
15 changes: 12 additions & 3 deletions pandas/_libs/tslibs/offsets.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -2518,7 +2518,7 @@ cdef class YearEnd(YearOffset):
"""

_default_month = 12
_prefix = "Y"
_prefix = "YE"
_day_opt = "end"

cdef readonly:
Expand Down Expand Up @@ -4562,7 +4562,7 @@ prefix_mapping = {
offset._prefix: offset
for offset in [
YearBegin, # 'YS'
YearEnd, # 'Y'
YearEnd, # 'YE'
BYearBegin, # 'BYS'
BYearEnd, # 'BY'
BusinessDay, # 'B'
Expand Down Expand Up @@ -4604,7 +4604,7 @@ _lite_rule_alias = {
"W": "W-SUN",
"QE": "QE-DEC",

"Y": "Y-DEC", # YearEnd(month=12),
"YE": "YE-DEC", # YearEnd(month=12),
"YS": "YS-JAN", # YearBegin(month=1),
"BY": "BY-DEC", # BYearEnd(month=12),
"BYS": "BYS-JAN", # BYearBegin(month=1),
Expand Down Expand Up @@ -4637,6 +4637,7 @@ _dont_uppercase = {
"qe-sep",
"qe-oct",
"qe-nov",
"ye",
}


Expand Down Expand Up @@ -4762,6 +4763,14 @@ cpdef to_offset(freq, bint is_period=False):
f"instead of \'{name}\'"
)
elif is_period is True and name in c_OFFSET_DEPR_FREQSTR:
if name.startswith("A"):
warnings.warn(
f"\'{name}\' is deprecated and will be removed in a future "
f"version, please use \'{c_DEPR_ABBREVS.get(name)}\' "
f"instead.",
FutureWarning,
stacklevel=find_stack_level(),
)
name = c_OFFSET_DEPR_FREQSTR.get(name)

if sep != "" and not sep.isspace():
Expand Down
6 changes: 3 additions & 3 deletions pandas/core/arrays/datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1520,7 +1520,7 @@ def isocalendar(self) -> DataFrame:
Examples
--------
>>> datetime_series = pd.Series(
... pd.date_range("2000-01-01", periods=3, freq="Y")
... pd.date_range("2000-01-01", periods=3, freq="YE")
... )
>>> datetime_series
0 2000-12-31
Expand Down Expand Up @@ -2058,10 +2058,10 @@ def isocalendar(self) -> DataFrame:
This method is available on Series with datetime values under
the ``.dt`` accessor, and directly on DatetimeIndex.
>>> idx = pd.date_range("2012-01-01", "2015-01-01", freq="Y")
>>> idx = pd.date_range("2012-01-01", "2015-01-01", freq="YE")
>>> idx
DatetimeIndex(['2012-12-31', '2013-12-31', '2014-12-31'],
dtype='datetime64[ns]', freq='Y-DEC')
dtype='datetime64[ns]', freq='YE-DEC')
>>> idx.is_leap_year
array([ True, False, False])
Expand Down
4 changes: 2 additions & 2 deletions pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -9199,11 +9199,11 @@ def resample(
Use frame.T.resample(...) instead.
closed : {{'right', 'left'}}, default None
Which side of bin interval is closed. The default is 'left'
for all frequency offsets except for 'ME', 'Y', 'Q', 'BME',
for all frequency offsets except for 'ME', 'YE', 'QE', 'BME',
'BA', 'BQ', and 'W' which all have a default of 'right'.
label : {{'right', 'left'}}, default None
Which bin edge label to label bucket with. The default is 'left'
for all frequency offsets except for 'ME', 'Y', 'Q', 'BME',
for all frequency offsets except for 'ME', 'YE', 'QE', 'BME',
'BA', 'BQ', and 'W' which all have a default of 'right'.
convention : {{'start', 'end', 's', 'e'}}, default 'start'
For `PeriodIndex` only, controls whether to use the start or
Expand Down
4 changes: 2 additions & 2 deletions pandas/core/resample.py
Original file line number Diff line number Diff line change
Expand Up @@ -2130,7 +2130,7 @@ def __init__(
else:
freq = to_offset(freq)

end_types = {"ME", "Y", "QE", "BME", "BY", "BQ", "W"}
end_types = {"ME", "YE", "QE", "BME", "BY", "BQ", "W"}
rule = freq.rule_code
if rule in end_types or ("-" in rule and rule[: rule.find("-")] in end_types):
if closed is None:
Expand Down Expand Up @@ -2330,7 +2330,7 @@ def _adjust_bin_edges(
"BQ",
"BY",
"QE",
"Y",
"YE",
"W",
):
# If the right end-point is on the last day of the month, roll forwards
Expand Down
2 changes: 1 addition & 1 deletion pandas/core/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -5785,7 +5785,7 @@ def to_timestamp(
2023-01-31 1
2024-01-31 2
2025-01-31 3
Freq: Y-JAN, dtype: int64
Freq: YE-JAN, dtype: int64
"""
if not isinstance(self.index, PeriodIndex):
raise TypeError(f"unsupported Type {type(self.index).__name__}")
Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/arithmetic/test_datetime64.py
Original file line number Diff line number Diff line change
Expand Up @@ -1606,7 +1606,7 @@ def test_dt64_series_arith_overflow(self):
# GH#12534, fixed by GH#19024
dt = Timestamp("1700-01-31")
td = Timedelta("20000 Days")
dti = date_range("1949-09-30", freq="100Y", periods=4)
dti = date_range("1949-09-30", freq="100YE", periods=4)
ser = Series(dti)
msg = "Overflow in int64 addition"
with pytest.raises(OverflowError, match=msg):
Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/arrays/period/test_arrow_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def test_arrow_extension_type():
"data, freq",
[
(pd.date_range("2017", periods=3), "D"),
(pd.date_range("2017", periods=3, freq="Y"), "Y-DEC"),
(pd.date_range("2017", periods=3, freq="YE"), "Y-DEC"),
],
)
def test_arrow_array(data, freq):
Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/arrays/test_datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@


# TODO: more freq variants
@pytest.fixture(params=["D", "B", "W", "ME", "QE", "Y"])
@pytest.fixture(params=["D", "B", "W", "ME", "QE", "YE"])
def freqstr(request):
"""Fixture returning parametrized frequency in string format."""
return request.param
Expand Down
8 changes: 6 additions & 2 deletions pandas/tests/arrays/test_datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -748,10 +748,14 @@ def test_iter_zoneinfo_fold(self, tz):
("2ME", "2M"),
("2QE", "2Q"),
("2QE-SEP", "2Q-SEP"),
("1YE", "1Y"),
("2YE-MAR", "2Y-MAR"),
("1YE", "1A"),
("2YE-MAR", "2A-MAR"),
],
)
def test_date_range_frequency_M_Q_deprecated(self, freq, freq_depr):
# GH#9586
def test_date_range_frequency_M_Q_Y_A_deprecated(self, freq, freq_depr):
# GH#9586, GH#54275
depr_msg = (
f"'{freq_depr[1:]}' will be deprecated, please use '{freq[1:]}' instead."
)
Expand Down
6 changes: 5 additions & 1 deletion pandas/tests/frame/methods/test_asfreq.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,9 +240,13 @@ def test_asfreq_2ME(self, freq, freq_half):
("2ME", "2M"),
("2QE", "2Q"),
("2QE-SEP", "2Q-SEP"),
("1YE", "1Y"),
("2YE-MAR", "2Y-MAR"),
("1YE", "1A"),
("2YE-MAR", "2A-MAR"),
],
)
def test_asfreq_frequency_M_Q_deprecated(self, freq, freq_depr):
def test_asfreq_frequency_M_Q_Y_A_deprecated(self, freq, freq_depr):
# GH#9586
depr_msg = (
f"'{freq_depr[1:]}' will be deprecated, please use '{freq[1:]}' instead."
Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/frame/methods/test_reindex.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def test_dti_set_index_reindex_datetimeindex(self):
# GH#6631
df = DataFrame(np.random.default_rng(2).random(6))
idx1 = date_range("2011/01/01", periods=6, freq="ME", tz="US/Eastern")
idx2 = date_range("2013", periods=6, freq="Y", tz="Asia/Tokyo")
idx2 = date_range("2013", periods=6, freq="YE", tz="Asia/Tokyo")

df = df.set_index(idx1)
tm.assert_index_equal(df.index, idx1)
Expand Down
6 changes: 3 additions & 3 deletions pandas/tests/frame/methods/test_to_timestamp.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import pandas._testing as tm


def _get_with_delta(delta, freq="Y-DEC"):
def _get_with_delta(delta, freq="YE-DEC"):
return date_range(
to_datetime("1/1/2001") + delta,
to_datetime("12/31/2009") + delta,
Expand All @@ -36,7 +36,7 @@ def test_to_timestamp(self, frame_or_series):
obj["mix"] = "a"
obj = tm.get_obj(obj, frame_or_series)

exp_index = date_range("1/1/2001", end="12/31/2009", freq="Y-DEC")
exp_index = date_range("1/1/2001", end="12/31/2009", freq="YE-DEC")
exp_index = exp_index + Timedelta(1, "D") - Timedelta(1, "ns")
result = obj.to_timestamp("D", "end")
tm.assert_index_equal(result.index, exp_index)
Expand Down Expand Up @@ -82,7 +82,7 @@ def test_to_timestamp_columns(self):
# columns
df = df.T

exp_index = date_range("1/1/2001", end="12/31/2009", freq="Y-DEC")
exp_index = date_range("1/1/2001", end="12/31/2009", freq="YE-DEC")
exp_index = exp_index + Timedelta(1, "D") - Timedelta(1, "ns")
result = df.to_timestamp("D", "end", axis=1)
tm.assert_index_equal(result.columns, exp_index)
Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/frame/test_repr.py
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ def test_repr_np_nat_with_object(self, arg, box, expected):
assert result == expected

def test_frame_datetime64_pre1900_repr(self):
df = DataFrame({"year": date_range("1/1/1700", periods=50, freq="Y-DEC")})
df = DataFrame({"year": date_range("1/1/1700", periods=50, freq="YE-DEC")})
# it works!
repr(df)

Expand Down
6 changes: 3 additions & 3 deletions pandas/tests/groupby/test_timegrouper.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ def test_timegrouper_with_reg_groups(self):
).set_index(["Date", "Buyer"])

msg = "The default value of numeric_only"
result = df.groupby([Grouper(freq="Y"), "Buyer"]).sum(numeric_only=True)
result = df.groupby([Grouper(freq="YE"), "Buyer"]).sum(numeric_only=True)
tm.assert_frame_equal(result, expected)

expected = DataFrame(
Expand Down Expand Up @@ -335,7 +335,7 @@ def test_timegrouper_with_reg_groups(self):
)
tm.assert_frame_equal(result, expected)

@pytest.mark.parametrize("freq", ["D", "ME", "Y", "QE-APR"])
@pytest.mark.parametrize("freq", ["D", "ME", "YE", "QE-APR"])
def test_timegrouper_with_reg_groups_freq(self, freq):
# GH 6764 multiple grouping with/without sort
df = DataFrame(
Expand Down Expand Up @@ -906,7 +906,7 @@ def test_groupby_apply_timegrouper_with_nat_apply_squeeze(

# We need to create a GroupBy object with only one non-NaT group,
# so use a huge freq so that all non-NaT dates will be grouped together
tdg = Grouper(key="Date", freq="100Y")
tdg = Grouper(key="Date", freq="100YE")
gb = df.groupby(tdg)

# check that we will go through the singular_series path
Expand Down
Loading

0 comments on commit 7e0d36f

Please sign in to comment.