Skip to content

Commit

Permalink
ENH: Use 'Y' as an alias for end of year
Browse files Browse the repository at this point in the history
Redo of gh-16958.
Closes gh-9313.
  • Loading branch information
gfyoung committed Jul 16, 2017
1 parent 7ffe7fc commit 0ed47f6
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 14 deletions.
2 changes: 1 addition & 1 deletion doc/source/timeseries.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1092,7 +1092,7 @@ frequencies. We will refer to these aliases as *offset aliases*
"BQ", "business quarter endfrequency"
"QS", "quarter start frequency"
"BQS", "business quarter start frequency"
"A", "year end frequency"
"A, Y", "year end frequency"
"BA", "business year end frequency"
"AS", "year start frequency"
"BAS", "business year start frequency"
Expand Down
1 change: 1 addition & 0 deletions doc/source/whatsnew/v0.21.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Other Enhancements
- :func:`DataFrame.clip()` and :func:`Series.clip()` have gained an ``inplace`` argument. (:issue:`15388`)
- :func:`crosstab` has gained a ``margins_name`` parameter to define the name of the row / column that will contain the totals when ``margins=True``. (:issue:`15972`)
- :func:`DataFrame.select_dtypes` now accepts scalar values for include/exclude as well as list-like. (:issue:`16855`)
- :func:`date_range` now accepts 'Y' in addition to 'A' as an alias for end of year (:issue:`9313`)

.. _whatsnew_0210.api_breaking:

Expand Down
41 changes: 28 additions & 13 deletions pandas/tests/tseries/test_frequencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,9 +248,10 @@ def test_anchored_shortcuts(self):

# ensure invalid cases fail as expected
invalid_anchors = ['SM-0', 'SM-28', 'SM-29',
'SM-FOO', 'BSM', 'SM--1'
'SM-FOO', 'BSM', 'SM--1',
'SMS-1', 'SMS-28', 'SMS-30',
'SMS-BAR', 'BSMS', 'SMS--2']
'SMS-BAR', 'SMS-BYR' 'BSMS',
'SMS--2']
for invalid_anchor in invalid_anchors:
with tm.assert_raises_regex(ValueError,
'Invalid frequency: '):
Expand Down Expand Up @@ -292,11 +293,15 @@ def test_get_rule_month():

result = frequencies._get_rule_month('A-DEC')
assert (result == 'DEC')
result = frequencies._get_rule_month('Y-DEC')
assert (result == 'DEC')
result = frequencies._get_rule_month(offsets.YearEnd())
assert (result == 'DEC')

result = frequencies._get_rule_month('A-MAY')
assert (result == 'MAY')
result = frequencies._get_rule_month('Y-MAY')
assert (result == 'MAY')
result = frequencies._get_rule_month(offsets.YearEnd(month=5))
assert (result == 'MAY')

Expand All @@ -305,6 +310,10 @@ def test_period_str_to_code():
assert (frequencies._period_str_to_code('A') == 1000)
assert (frequencies._period_str_to_code('A-DEC') == 1000)
assert (frequencies._period_str_to_code('A-JAN') == 1001)
assert (frequencies._period_str_to_code('Y') == 1000)
assert (frequencies._period_str_to_code('Y-DEC') == 1000)
assert (frequencies._period_str_to_code('Y-JAN') == 1001)

assert (frequencies._period_str_to_code('Q') == 2000)
assert (frequencies._period_str_to_code('Q-DEC') == 2000)
assert (frequencies._period_str_to_code('Q-FEB') == 2002)
Expand Down Expand Up @@ -349,6 +358,10 @@ def test_freq_code(self):
assert frequencies.get_freq('3A') == 1000
assert frequencies.get_freq('-1A') == 1000

assert frequencies.get_freq('Y') == 1000
assert frequencies.get_freq('3Y') == 1000
assert frequencies.get_freq('-1Y') == 1000

assert frequencies.get_freq('W') == 4000
assert frequencies.get_freq('W-MON') == 4001
assert frequencies.get_freq('W-FRI') == 4005
Expand All @@ -369,6 +382,13 @@ def test_freq_group(self):
assert frequencies.get_freq_group('-1A') == 1000
assert frequencies.get_freq_group('A-JAN') == 1000
assert frequencies.get_freq_group('A-MAY') == 1000

assert frequencies.get_freq_group('Y') == 1000
assert frequencies.get_freq_group('3Y') == 1000
assert frequencies.get_freq_group('-1Y') == 1000
assert frequencies.get_freq_group('Y-JAN') == 1000
assert frequencies.get_freq_group('Y-MAY') == 1000

assert frequencies.get_freq_group(offsets.YearEnd()) == 1000
assert frequencies.get_freq_group(offsets.YearEnd(month=1)) == 1000
assert frequencies.get_freq_group(offsets.YearEnd(month=5)) == 1000
Expand Down Expand Up @@ -790,12 +810,6 @@ def test_series(self):
for freq in [None, 'L']:
s = Series(period_range('2013', periods=10, freq=freq))
pytest.raises(TypeError, lambda: frequencies.infer_freq(s))
for freq in ['Y']:

msg = frequencies._INVALID_FREQ_ERROR
with tm.assert_raises_regex(ValueError, msg):
s = Series(period_range('2013', periods=10, freq=freq))
pytest.raises(TypeError, lambda: frequencies.infer_freq(s))

# DateTimeIndex
for freq in ['M', 'L', 'S']:
Expand All @@ -812,11 +826,12 @@ def test_legacy_offset_warnings(self):
'W@FRI', 'W@SAT', 'W@SUN', 'Q@JAN', 'Q@FEB', 'Q@MAR',
'A@JAN', 'A@FEB', 'A@MAR', 'A@APR', 'A@MAY', 'A@JUN',
'A@JUL', 'A@AUG', 'A@SEP', 'A@OCT', 'A@NOV', 'A@DEC',
'WOM@1MON', 'WOM@2MON', 'WOM@3MON', 'WOM@4MON',
'WOM@1TUE', 'WOM@2TUE', 'WOM@3TUE', 'WOM@4TUE',
'WOM@1WED', 'WOM@2WED', 'WOM@3WED', 'WOM@4WED',
'WOM@1THU', 'WOM@2THU', 'WOM@3THU', 'WOM@4THU'
'WOM@1FRI', 'WOM@2FRI', 'WOM@3FRI', 'WOM@4FRI']
'Y@JAN', 'WOM@1MON', 'WOM@2MON', 'WOM@3MON',
'WOM@4MON', 'WOM@1TUE', 'WOM@2TUE', 'WOM@3TUE',
'WOM@4TUE', 'WOM@1WED', 'WOM@2WED', 'WOM@3WED',
'WOM@4WED', 'WOM@1THU', 'WOM@2THU', 'WOM@3THU',
'WOM@4THU', 'WOM@1FRI', 'WOM@2FRI', 'WOM@3FRI',
'WOM@4FRI']

msg = frequencies._INVALID_FREQ_ERROR
for freq in freqs:
Expand Down
22 changes: 22 additions & 0 deletions pandas/tseries/frequencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,27 @@ def get_period_alias(offset_str):
return _offset_to_period_map.get(offset_str, None)


_pure_alias = {
# 'A' is equivalent to 'Y'.
'Y': 'A',
'YS': 'AS',
'BY': 'BA',
'BYS': 'BAS',
'Y-DEC': 'A-DEC',
'Y-JAN': 'A-JAN',
'Y-FEB': 'A-FEB',
'Y-MAR': 'A-MAR',
'Y-APR': 'A-APR',
'Y-MAY': 'A-MAY',
'Y-JUN': 'A-JUN',
'Y-JUL': 'A-JUL',
'Y-AUG': 'A-AUG',
'Y-SEP': 'A-SEP',
'Y-OCT': 'A-OCT',
'Y-NOV': 'A-NOV',
}


_lite_rule_alias = {
'W': 'W-SUN',
'Q': 'Q-DEC',
Expand Down Expand Up @@ -718,6 +739,7 @@ def get_standard_freq(freq):


def _period_str_to_code(freqstr):
freqstr = _pure_alias.get(freqstr, freqstr)
freqstr = _lite_rule_alias.get(freqstr, freqstr)

if freqstr not in _dont_uppercase:
Expand Down

0 comments on commit 0ed47f6

Please sign in to comment.