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: rename BQ to BQE for offsets #55978

Merged
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
6 changes: 3 additions & 3 deletions doc/source/user_guide/timeseries.rst
Original file line number Diff line number Diff line change
Expand Up @@ -886,7 +886,7 @@ into ``freq`` keyword arguments. The available date offsets and associated frequ
:class:`~pandas.tseries.offsets.SemiMonthBegin`, ``'SMS'``, "15th (or other day_of_month) and calendar month begin"
:class:`~pandas.tseries.offsets.QuarterEnd`, ``'QE'``, "calendar quarter end"
:class:`~pandas.tseries.offsets.QuarterBegin`, ``'QS'``, "calendar quarter begin"
:class:`~pandas.tseries.offsets.BQuarterEnd`, ``'BQ``, "business quarter end"
:class:`~pandas.tseries.offsets.BQuarterEnd`, ``'BQE``, "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`, ``'YE'``, "calendar year end"
Expand Down Expand Up @@ -1249,7 +1249,7 @@ frequencies. We will refer to these aliases as *offset aliases*.
"BMS", "business month start frequency"
"CBMS", "custom business month start frequency"
"QE", "quarter end frequency"
"BQ", "business quarter end frequency"
"BQE", "business quarter end frequency"
"QS", "quarter start frequency"
"BQS", "business quarter start frequency"
"YE", "year end frequency"
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', 'YE', 'QE', 'BME', 'BY', 'BQ', and 'W'
frequency offsets except for 'ME', 'YE', 'QE', 'BME', 'BY', 'BQE', and 'W'
which all have a default of 'right'.

This might unintendedly lead to looking ahead, where the value for a later
Expand Down
1 change: 1 addition & 0 deletions doc/source/whatsnew/v2.2.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ Other Deprecations
- Deprecated string ``A`` denoting frequency in :class:`YearEnd` and strings ``A-DEC``, ``A-JAN``, etc. denoting annual frequencies with various fiscal year ends (:issue:`54275`)
- Deprecated string ``BAS`` denoting frequency in :class:`BYearBegin` and strings ``BAS-DEC``, ``BAS-JAN``, etc. denoting annual frequencies with various fiscal year starts (:issue:`54275`)
- Deprecated string ``BA`` denoting frequency in :class:`BYearEnd` and strings ``BA-DEC``, ``BA-JAN``, etc. denoting annual frequencies with various fiscal year ends (:issue:`54275`)
- Deprecated string ``BQ`` denoting frequency in :class:`BQuarterEnd` (:issue:`52064`)
- Deprecated strings ``BM``, and ``CBM`` denoting frequencies in :class:`BusinessMonthEnd`, :class:`CustomBusinessMonthEnd` (:issue:`52064`)
- Deprecated strings ``H``, ``BH``, and ``CBH`` denoting frequencies in :class:`Hour`, :class:`BusinessHour`, :class:`CustomBusinessHour` (:issue:`52536`)
- Deprecated strings ``H``, ``S``, ``U``, and ``N`` denoting units in :func:`to_timedelta` (:issue:`52536`)
Expand Down
29 changes: 28 additions & 1 deletion pandas/_libs/tslibs/dtypes.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,19 @@ OFFSET_TO_PERIOD_FREQSTR: dict = {
"BME": "M",
"BQS": "Q",
"QS": "Q",
"BQ": "Q",
"BQE": "Q",
"BQE-DEC": "Q-DEC",
"BQE-JAN": "Q-JAN",
"BQE-FEB": "Q-FEB",
"BQE-MAR": "Q-MAR",
"BQE-APR": "Q-APR",
"BQE-MAY": "Q-MAY",
"BQE-JUN": "Q-JUN",
"BQE-JUL": "Q-JUL",
"BQE-AUG": "Q-AUG",
"BQE-SEP": "Q-SEP",
"BQE-OCT": "Q-OCT",
"BQE-NOV": "Q-NOV",
"MS": "M",
"D": "D",
"B": "B",
Expand Down Expand Up @@ -275,6 +287,21 @@ OFFSET_DEPR_FREQSTR: dict[str, str]= {
"A-SEP": "YE-SEP",
"A-OCT": "YE-OCT",
"A-NOV": "YE-NOV",
"BM": "BME",
"CBM": "CBME",
"BQ": "BQE",
"BQ-DEC": "BQE-DEC",
"BQ-JAN": "BQE-JAN",
"BQ-FEB": "BQE-FEB",
"BQ-MAR": "BQE-MAR",
"BQ-APR": "BQE-APR",
"BQ-MAY": "BQE-MAY",
"BQ-JUN": "BQE-JUN",
"BQ-JUL": "BQE-JUL",
"BQ-AUG": "BQE-AUG",
"BQ-SEP": "BQE-SEP",
"BQ-OCT": "BQE-OCT",
"BQ-NOV": "BQE-NOV",
}
cdef dict c_OFFSET_TO_PERIOD_FREQSTR = OFFSET_TO_PERIOD_FREQSTR
cdef dict c_OFFSET_DEPR_FREQSTR = OFFSET_DEPR_FREQSTR
Expand Down
6 changes: 3 additions & 3 deletions pandas/_libs/tslibs/offsets.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -2693,7 +2693,7 @@ cdef class BQuarterEnd(QuarterOffset):
_output_name = "BusinessQuarterEnd"
_default_starting_month = 3
_from_name_starting_month = 12
_prefix = "BQ"
_prefix = "BQE"
_day_opt = "business_end"


Expand Down Expand Up @@ -4568,7 +4568,7 @@ prefix_mapping = {
BusinessDay, # 'B'
BusinessMonthBegin, # 'BMS'
BusinessMonthEnd, # 'BME'
BQuarterEnd, # 'BQ'
BQuarterEnd, # 'BQE'
BQuarterBegin, # 'BQS'
BusinessHour, # 'bh'
CustomBusinessDay, # 'C'
Expand Down Expand Up @@ -4752,7 +4752,7 @@ cpdef to_offset(freq, bint is_period=False):
for n, (sep, stride, name) in enumerate(tups):
if is_period is False and name in c_OFFSET_DEPR_FREQSTR:
warnings.warn(
f"\'{name}\' will be deprecated, please use "
f"\'{name}\' is deprecated, please use "
f"\'{c_OFFSET_DEPR_FREQSTR.get(name)}\' instead.",
FutureWarning,
stacklevel=find_stack_level(),
Expand Down
4 changes: 2 additions & 2 deletions pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -9200,11 +9200,11 @@ def resample(
closed : {{'right', 'left'}}, default None
Which side of bin interval is closed. The default is 'left'
for all frequency offsets except for 'ME', 'YE', 'QE', 'BME',
'BA', 'BQ', and 'W' which all have a default of 'right'.
'BA', 'BQE', 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', 'YE', 'QE', 'BME',
'BA', 'BQ', and 'W' which all have a default of 'right'.
'BA', 'BQE', 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
end of `rule`.
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", "YE", "QE", "BME", "BY", "BQ", "W"}
end_types = {"ME", "YE", "QE", "BME", "BY", "BQE", "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 @@ -2327,7 +2327,7 @@ def _adjust_bin_edges(
# Some hacks for > daily data, see #1471, #1458, #1483

if self.freq.name in ("BME", "ME", "W") or self.freq.name.split("-")[0] in (
"BQ",
"BQE",
"BY",
"QE",
"YE",
Expand Down
4 changes: 1 addition & 3 deletions pandas/tests/arrays/test_datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -756,9 +756,7 @@ def test_iter_zoneinfo_fold(self, tz):
)
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."
)
depr_msg = f"'{freq_depr[1:]}' is deprecated, please use '{freq[1:]}' instead."

expected = pd.date_range("1/1/2000", periods=4, freq=freq)
with tm.assert_produces_warning(FutureWarning, match=depr_msg):
Expand Down
8 changes: 4 additions & 4 deletions pandas/tests/frame/methods/test_asfreq.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,17 +240,17 @@ def test_asfreq_2ME(self, freq, freq_half):
("2ME", "2M"),
("2QE", "2Q"),
("2QE-SEP", "2Q-SEP"),
("1BQE", "1BQ"),
("2BQE-SEP", "2BQ-SEP"),
("1YE", "1Y"),
("2YE-MAR", "2Y-MAR"),
("1YE", "1A"),
("2YE-MAR", "2A-MAR"),
],
)
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."
)
# GH#9586, #55978
depr_msg = f"'{freq_depr[1:]}' is deprecated, please use '{freq[1:]}' instead."

index = date_range("1/1/2000", periods=4, freq=f"{freq[1:]}")
df = DataFrame({"s": Series([0.0, 1.0, 2.0, 3.0], index=index)})
Expand Down
4 changes: 2 additions & 2 deletions pandas/tests/indexes/datetimes/methods/test_to_period.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def test_to_period_quarterly(self, month):
result = stamps.to_period(freq)
tm.assert_index_equal(rng, result)

@pytest.mark.parametrize("off", ["BQ", "QS", "BQS"])
@pytest.mark.parametrize("off", ["BQE", "QS", "BQS"])
def test_to_period_quarterlyish(self, off):
rng = date_range("01-Jan-2012", periods=8, freq=off)
prng = rng.to_period()
Expand Down Expand Up @@ -103,7 +103,7 @@ def test_dti_to_period_2monthish(self, freq_offset, freq_period):
)
def test_to_period_frequency_M_Q_Y_A_deprecated(self, freq, freq_depr):
# GH#9586
msg = f"'{freq_depr[1:]}' will be deprecated, please use '{freq[1:]}' instead."
msg = f"'{freq_depr[1:]}' is deprecated, please use '{freq[1:]}' instead."

rng = date_range("01-Jan-2012", periods=8, freq=freq)
prng = rng.to_period()
Expand Down
6 changes: 3 additions & 3 deletions pandas/tests/indexes/datetimes/test_date_range.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ def test_date_range_float_periods(self):
tm.assert_index_equal(rng, exp)

def test_date_range_frequency_M_deprecated(self):
depr_msg = "'M' will be deprecated, please use 'ME' instead."
depr_msg = "'M' is deprecated, please use 'ME' instead."

expected = date_range("1/1/2000", periods=4, freq="2ME")
with tm.assert_produces_warning(FutureWarning, match=depr_msg):
Expand Down Expand Up @@ -786,7 +786,7 @@ def test_frequencies_A_deprecated_Y_renamed(self, freq, freq_depr):
# GH#9586, GH#54275
freq_msg = re.split("[0-9]*", freq, maxsplit=1)[1]
freq_depr_msg = re.split("[0-9]*", freq_depr, maxsplit=1)[1]
msg = f"'{freq_depr_msg}' will be deprecated, please use '{freq_msg}' instead."
msg = f"'{freq_depr_msg}' is deprecated, please use '{freq_msg}' instead."

expected = date_range("1/1/2000", periods=2, freq=freq)
with tm.assert_produces_warning(FutureWarning, match=msg):
Expand Down Expand Up @@ -1645,7 +1645,7 @@ def test_date_range_fy5253(self, unit):
"freqstr,offset",
[
("QS", offsets.QuarterBegin(startingMonth=1)),
("BQ", offsets.BQuarterEnd(startingMonth=12)),
("BQE", offsets.BQuarterEnd(startingMonth=12)),
("W-SUN", offsets.Week(weekday=6)),
],
)
Expand Down
18 changes: 13 additions & 5 deletions pandas/tests/indexes/datetimes/test_datetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,16 +201,24 @@ def test_AS_BA_BAS_deprecated(self, freq_depr, expected_values, expected_freq):

tm.assert_index_equal(result, expected)

def test_BM_deprecated(self):
@pytest.mark.parametrize(
"freq, expected_values, freq_depr",
[
("2BME", ["2016-02-29", "2016-04-29", "2016-06-30"], "2BM"),
("2BQE", ["2016-03-31"], "2BQ"),
("1BQE-MAR", ["2016-03-31", "2016-06-30"], "1BQ-MAR"),
],
)
def test_BM_BQ_deprecated(self, freq, expected_values, freq_depr):
# GH#52064
msg = "'BM' is deprecated and will be removed in a future version."
msg = f"'{freq_depr[1:]}' is deprecated, please use '{freq[1:]}' instead."

with tm.assert_produces_warning(FutureWarning, match=msg):
expected = date_range(start="2016-02-21", end="2016-08-21", freq="2BM")
expected = date_range(start="2016-02-21", end="2016-08-21", freq=freq_depr)
result = DatetimeIndex(
["2016-02-29", "2016-04-29", "2016-06-30"],
data=expected_values,
dtype="datetime64[ns]",
freq="2BME",
freq=freq,
)

tm.assert_index_equal(result, expected)
2 changes: 1 addition & 1 deletion pandas/tests/indexes/datetimes/test_scalar_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ def test_dti_fields(self, tz):
tm.assert_index_equal(res, exp)

def test_dti_is_year_quarter_start(self):
dti = date_range(freq="BQ-FEB", start=datetime(1998, 1, 1), periods=4)
dti = date_range(freq="BQE-FEB", start=datetime(1998, 1, 1), periods=4)

assert sum(dti.is_quarter_start) == 0
assert sum(dti.is_quarter_end) == 4
Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/indexes/period/test_period.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ def test_a_deprecated_from_time_series(self, freq_depr):
series = Series(1, index=index)
assert isinstance(series, Series)

@pytest.mark.parametrize("freq_depr", ["2ME", "2QE", "2YE"])
@pytest.mark.parametrize("freq_depr", ["2ME", "2QE", "2BQE", "2YE"])
def test_period_index_frequency_error_message(self, freq_depr):
# GH#9586
msg = f"for Period, please use '{freq_depr[1:-1]}' "
Expand Down
18 changes: 13 additions & 5 deletions pandas/tests/resample/test_datetime_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -2058,7 +2058,7 @@ def test_resample_empty_series_with_tz():
)
def test_resample_M_Q_Y_A_deprecated(freq, freq_depr):
# GH#9586
depr_msg = f"'{freq_depr[1:]}' will be deprecated, please use '{freq[1:]}' instead."
depr_msg = f"'{freq_depr[1:]}' is deprecated, please use '{freq[1:]}' instead."

s = Series(range(10), index=date_range("20130101", freq="d", periods=10))
expected = s.resample(freq).mean()
Expand All @@ -2067,14 +2067,22 @@ def test_resample_M_Q_Y_A_deprecated(freq, freq_depr):
tm.assert_series_equal(result, expected)


def test_resample_BM_deprecated():
@pytest.mark.parametrize(
"freq, freq_depr",
[
("2BME", "2BM"),
("2BQE", "2BQ"),
("2BQE-MAR", "2BQ-MAR"),
],
)
def test_resample_BM_BQ_deprecated(freq, freq_depr):
# GH#52064
depr_msg = "'BM' is deprecated and will be removed in a future version."
depr_msg = f"'{freq_depr[1:]}' is deprecated, please use '{freq[1:]}' instead."

s = Series(range(10), index=date_range("20130101", freq="d", periods=10))
expected = s.resample("2BME").mean()
expected = s.resample(freq).mean()
with tm.assert_produces_warning(FutureWarning, match=depr_msg):
result = s.resample("2BM").mean()
result = s.resample(freq_depr).mean()
tm.assert_series_equal(result, expected)


Expand Down
7 changes: 5 additions & 2 deletions pandas/tests/resample/test_period_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -924,10 +924,13 @@ def test_resample_t_l_deprecated(self):
tm.assert_series_equal(result, expected)


@pytest.mark.parametrize("freq_depr", ["2ME", "2QE", "2QE-FEB", "2YE", "2YE-MAR"])
@pytest.mark.parametrize(
"freq_depr", ["2ME", "2QE", "2QE-FEB", "2BQE", "2BQE-FEB", "2YE", "2YE-MAR"]
)
def test_resample_frequency_ME_QE_error_message(series_and_frame, freq_depr):
# GH#9586
msg = f"for Period, please use '{freq_depr[1:2]}{freq_depr[3:]}' "
pos_e = freq_depr.index("E")
msg = f"for Period, please use '{freq_depr[1:pos_e]}{freq_depr[pos_e+1:]}' "
f"instead of '{freq_depr[1:]}'"

obj = series_and_frame
Expand Down
6 changes: 3 additions & 3 deletions pandas/tests/tseries/offsets/test_offsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -838,7 +838,7 @@ def test_rule_code(self):
"NOV",
"DEC",
]
base_lst = ["YE", "YS", "BY", "BYS", "QE", "QS", "BQ", "BQS"]
base_lst = ["YE", "YS", "BY", "BYS", "QE", "QS", "BQE", "BQS"]
for base in base_lst:
for v in suffix_lst:
alias = "-".join([base, v])
Expand All @@ -857,7 +857,7 @@ def test_freq_offsets():
class TestReprNames:
def test_str_for_named_is_name(self):
# look at all the amazing combinations!
month_prefixes = ["YE", "YS", "BY", "BYS", "QE", "BQ", "BQS", "QS"]
month_prefixes = ["YE", "YS", "BY", "BYS", "QE", "BQE", "BQS", "QS"]
names = [
prefix + "-" + month
for prefix in month_prefixes
Expand Down Expand Up @@ -1122,7 +1122,7 @@ def test_is_yqm_start_end():
bm = to_offset("BME")
qfeb = to_offset("QE-FEB")
qsfeb = to_offset("QS-FEB")
bq = to_offset("BQ")
bq = to_offset("BQE")
bqs_apr = to_offset("BQS-APR")
as_nov = to_offset("YS-NOV")

Expand Down
4 changes: 2 additions & 2 deletions pandas/tseries/frequencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
# --------------------------------------------------------------------
# Offset related functions

_need_suffix = ["QS", "BQ", "BQS", "YS", "BY", "BYS"]
_need_suffix = ["QS", "BQE", "BQS", "YS", "BY", "BYS"]

for _prefix in _need_suffix:
for _m in MONTHS:
Expand Down Expand Up @@ -359,7 +359,7 @@ def _get_quarterly_rule(self) -> str | None:
if pos_check is None:
return None
else:
return {"cs": "QS", "bs": "BQS", "ce": "QE", "be": "BQ"}.get(pos_check)
return {"cs": "QS", "bs": "BQS", "ce": "QE", "be": "BQE"}.get(pos_check)

def _get_monthly_rule(self) -> str | None:
if len(self.mdiffs) > 1:
Expand Down