Skip to content

Commit 5a92d48

Browse files
mathausemax-sixtyspencerkclark
authored
rename "Y" freq string to "YE" (pandas parity) (#8629)
* rename "Y" freq string to "YE" (pandas parity) * Update xarray/coding/cftime_offsets.py Co-authored-by: Spencer Clark <[email protected]> * fix table * changelog * remove unneeded elif branch --------- Co-authored-by: Maximilian Roos <[email protected]> Co-authored-by: Spencer Clark <[email protected]>
1 parent e571d1c commit 5a92d48

File tree

3 files changed

+38
-26
lines changed

3 files changed

+38
-26
lines changed

doc/whats-new.rst

+9
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,19 @@ New Features
2626
Breaking changes
2727
~~~~~~~~~~~~~~~~
2828

29+
- Following pandas, :py:meth:`infer_freq` will return ``"YE"``, instead of ``"Y"`` (formerly ``"A"``).
30+
This is to be consistent with the deprecation of the latter frequency string in pandas 2.2.
31+
This is a follow up to :pull:`8415` (:issue:`8612`, :pull:`8629`).
32+
By `Mathias Hauser <https://github.com/mathause>`_.
2933

3034
Deprecations
3135
~~~~~~~~~~~~
3236

37+
- Following pandas, the frequency string ``"Y"`` (formerly ``"A"``) is deprecated in
38+
favor of ``"YE"``. These strings are used, for example, in :py:func:`date_range`,
39+
:py:func:`cftime_range`, :py:meth:`DataArray.resample`, and :py:meth:`Dataset.resample`
40+
among others (:issue:`8612`, :pull:`8629`).
41+
By `Mathias Hauser <https://github.com/mathause>`_.
3342

3443
Bug fixes
3544
~~~~~~~~~

xarray/coding/cftime_offsets.py

+22-21
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ def rollback(self, date):
573573

574574

575575
class YearEnd(YearOffset):
576-
_freq = "Y"
576+
_freq = "YE"
577577
_day_option = "end"
578578
_default_month = 12
579579

@@ -669,6 +669,7 @@ def _generate_anchored_offsets(base_freq, offset):
669669
"A": YearEnd,
670670
"AS": YearBegin,
671671
"Y": YearEnd,
672+
"YE": YearEnd,
672673
"YS": YearBegin,
673674
"Q": partial(QuarterEnd, month=12),
674675
"QE": partial(QuarterEnd, month=12),
@@ -691,6 +692,7 @@ def _generate_anchored_offsets(base_freq, offset):
691692
**_generate_anchored_offsets("A", YearEnd),
692693
**_generate_anchored_offsets("YS", YearBegin),
693694
**_generate_anchored_offsets("Y", YearEnd),
695+
**_generate_anchored_offsets("YE", YearEnd),
694696
**_generate_anchored_offsets("QS", QuarterBegin),
695697
**_generate_anchored_offsets("Q", QuarterEnd),
696698
**_generate_anchored_offsets("QE", QuarterEnd),
@@ -716,7 +718,8 @@ def _generate_anchored_deprecated_frequencies(deprecated, recommended):
716718

717719

718720
_DEPRECATED_FREQUENICES = {
719-
"A": "Y",
721+
"A": "YE",
722+
"Y": "YE",
720723
"AS": "YS",
721724
"Q": "QE",
722725
"M": "ME",
@@ -725,7 +728,8 @@ def _generate_anchored_deprecated_frequencies(deprecated, recommended):
725728
"S": "s",
726729
"L": "ms",
727730
"U": "us",
728-
**_generate_anchored_deprecated_frequencies("A", "Y"),
731+
**_generate_anchored_deprecated_frequencies("A", "YE"),
732+
**_generate_anchored_deprecated_frequencies("Y", "YE"),
729733
**_generate_anchored_deprecated_frequencies("AS", "YS"),
730734
**_generate_anchored_deprecated_frequencies("Q", "QE"),
731735
}
@@ -979,7 +983,7 @@ def cftime_range(
979983
+--------+--------------------------+
980984
| Alias | Description |
981985
+========+==========================+
982-
| Y | Year-end frequency |
986+
| YE | Year-end frequency |
983987
+--------+--------------------------+
984988
| YS | Year-start frequency |
985989
+--------+--------------------------+
@@ -1009,29 +1013,29 @@ def cftime_range(
10091013
+------------+--------------------------------------------------------------------+
10101014
| Alias | Description |
10111015
+============+====================================================================+
1012-
| Y(S)-JAN | Annual frequency, anchored at the end (or beginning) of January |
1016+
| Y(E,S)-JAN | Annual frequency, anchored at the (end, beginning) of January |
10131017
+------------+--------------------------------------------------------------------+
1014-
| Y(S)-FEB | Annual frequency, anchored at the end (or beginning) of February |
1018+
| Y(E,S)-FEB | Annual frequency, anchored at the (end, beginning) of February |
10151019
+------------+--------------------------------------------------------------------+
1016-
| Y(S)-MAR | Annual frequency, anchored at the end (or beginning) of March |
1020+
| Y(E,S)-MAR | Annual frequency, anchored at the (end, beginning) of March |
10171021
+------------+--------------------------------------------------------------------+
1018-
| Y(S)-APR | Annual frequency, anchored at the end (or beginning) of April |
1022+
| Y(E,S)-APR | Annual frequency, anchored at the (end, beginning) of April |
10191023
+------------+--------------------------------------------------------------------+
1020-
| Y(S)-MAY | Annual frequency, anchored at the end (or beginning) of May |
1024+
| Y(E,S)-MAY | Annual frequency, anchored at the (end, beginning) of May |
10211025
+------------+--------------------------------------------------------------------+
1022-
| Y(S)-JUN | Annual frequency, anchored at the end (or beginning) of June |
1026+
| Y(E,S)-JUN | Annual frequency, anchored at the (end, beginning) of June |
10231027
+------------+--------------------------------------------------------------------+
1024-
| Y(S)-JUL | Annual frequency, anchored at the end (or beginning) of July |
1028+
| Y(E,S)-JUL | Annual frequency, anchored at the (end, beginning) of July |
10251029
+------------+--------------------------------------------------------------------+
1026-
| Y(S)-AUG | Annual frequency, anchored at the end (or beginning) of August |
1030+
| Y(E,S)-AUG | Annual frequency, anchored at the (end, beginning) of August |
10271031
+------------+--------------------------------------------------------------------+
1028-
| Y(S)-SEP | Annual frequency, anchored at the end (or beginning) of September |
1032+
| Y(E,S)-SEP | Annual frequency, anchored at the (end, beginning) of September |
10291033
+------------+--------------------------------------------------------------------+
1030-
| Y(S)-OCT | Annual frequency, anchored at the end (or beginning) of October |
1034+
| Y(E,S)-OCT | Annual frequency, anchored at the (end, beginning) of October |
10311035
+------------+--------------------------------------------------------------------+
1032-
| Y(S)-NOV | Annual frequency, anchored at the end (or beginning) of November |
1036+
| Y(E,S)-NOV | Annual frequency, anchored at the (end, beginning) of November |
10331037
+------------+--------------------------------------------------------------------+
1034-
| Y(S)-DEC | Annual frequency, anchored at the end (or beginning) of December |
1038+
| Y(E,S)-DEC | Annual frequency, anchored at the (end, beginning) of December |
10351039
+------------+--------------------------------------------------------------------+
10361040
| Q(E,S)-JAN | Quarter frequency, anchored at the (end, beginning) of January |
10371041
+------------+--------------------------------------------------------------------+
@@ -1311,11 +1315,8 @@ def date_range_like(source, calendar, use_cftime=None):
13111315
freq = freq.replace("QE", "Q")
13121316
elif isinstance(freq_as_offset, YearBegin) and "YS" in freq:
13131317
freq = freq.replace("YS", "AS")
1314-
elif isinstance(freq_as_offset, YearEnd) and "Y-" in freq:
1315-
# Check for and replace "Y-" instead of just "Y" to prevent
1316-
# corrupting anchored offsets that contain "Y" in the month
1317-
# abbreviation, e.g. "Y-MAY" -> "A-MAY".
1318-
freq = freq.replace("Y-", "A-")
1318+
elif isinstance(freq_as_offset, YearEnd) and "YE" in freq:
1319+
freq = freq.replace("YE", "A")
13191320

13201321
use_cftime = _should_cftime_be_used(source, calendar, use_cftime)
13211322

xarray/tests/test_cftime_offsets.py

+7-5
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ def test_year_offset_constructor_invalid_month(offset, invalid_month, exception)
157157
(MonthBegin(), "MS"),
158158
(MonthEnd(), "ME"),
159159
(YearBegin(), "YS-JAN"),
160-
(YearEnd(), "Y-DEC"),
160+
(YearEnd(), "YE-DEC"),
161161
(QuarterBegin(), "QS-MAR"),
162162
(QuarterEnd(), "QE-MAR"),
163163
(Day(), "D"),
@@ -1387,7 +1387,7 @@ def test_date_range_errors() -> None:
13871387
("2020-02-01", "ME", "noleap", "gregorian", True, "2020-02-29", True),
13881388
("2020-02-01", "QE-DEC", "noleap", "gregorian", True, "2020-03-31", True),
13891389
("2020-02-01", "YS-FEB", "noleap", "gregorian", True, "2020-02-01", True),
1390-
("2020-02-01", "Y-FEB", "noleap", "gregorian", True, "2020-02-29", True),
1390+
("2020-02-01", "YE-FEB", "noleap", "gregorian", True, "2020-02-29", True),
13911391
("2020-02-28", "3h", "all_leap", "gregorian", False, "2020-02-28", True),
13921392
("2020-03-30", "ME", "360_day", "gregorian", False, "2020-03-31", True),
13931393
("2020-03-31", "ME", "gregorian", "360_day", None, "2020-03-30", False),
@@ -1409,8 +1409,8 @@ def test_date_range_like(start, freq, cal_src, cal_tgt, use_cftime, exp0, exp_pd
14091409
elif "YS" in freq:
14101410
freq = freq.replace("YS", "AS")
14111411
expected_pandas_freq = freq
1412-
elif "Y-" in freq:
1413-
freq = freq.replace("Y-", "A-")
1412+
elif "YE-" in freq:
1413+
freq = freq.replace("YE-", "A-")
14141414
expected_pandas_freq = freq
14151415
elif "h" in freq:
14161416
expected_pandas_freq = freq.replace("h", "H")
@@ -1534,7 +1534,9 @@ def test_cftime_or_date_range_inclusive_None(function) -> None:
15341534
np.testing.assert_equal(result_None.values, result_both.values)
15351535

15361536

1537-
@pytest.mark.parametrize("freq", ["A", "AS", "Q", "M", "H", "T", "S", "L", "U"])
1537+
@pytest.mark.parametrize(
1538+
"freq", ["A", "AS", "Q", "M", "H", "T", "S", "L", "U", "Y", "A-MAY"]
1539+
)
15381540
def test_to_offset_deprecation_warning(freq):
15391541
# Test for deprecations outlined in GitHub issue #8394
15401542
with pytest.warns(FutureWarning, match="is deprecated"):

0 commit comments

Comments
 (0)