Skip to content

Commit

Permalink
BUG: Can't get period code with frequency alias 'minute' or 'Minute'
Browse files Browse the repository at this point in the history
closes #11854
closes #12540
  • Loading branch information
sinhrks authored and jreback committed Mar 15, 2016
1 parent 4973c59 commit 4da9b15
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 6 deletions.
2 changes: 2 additions & 0 deletions doc/source/whatsnew/v0.18.1.txt
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ Performance Improvements
Bug Fixes
~~~~~~~~~

- Bug in ``Period`` and ``PeriodIndex`` creation raises ``KeyError`` if ``freq="Minute"`` is specified. Note that "Minute" freq is deprecated in v0.17.0, and recommended to use ``freq="T"`` instead (:issue:`11854`)

- Bug in ``value_counts`` when ``normalize=True`` and ``dropna=True`` where nulls still contributed to the normalized count (:issue:`12558`)

- Bug in ``CategoricalIndex.get_loc`` returns different result from regular ``Index`` (:issue:`12531`)
1 change: 1 addition & 0 deletions pandas/src/period.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,7 @@ cdef class Period(object):

if isinstance(freq, compat.string_types):
from pandas.tseries.frequencies import _period_alias_dict
freq = freq.upper()
freq = _period_alias_dict.get(freq, freq)
elif isinstance(freq, (int, tuple)):
from pandas.tseries.frequencies import get_freq_code as _gfc
Expand Down
7 changes: 4 additions & 3 deletions pandas/tseries/frequencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,8 @@ def get_period_alias(offset_str):
'Min': 'T',
'min': 'T',
'ms': 'L',
'us': 'U'
'us': 'U',
'ns': 'N'
}

# TODO: Can this be killed?
Expand Down Expand Up @@ -683,7 +684,7 @@ def _period_alias_dictionary():
alias_dict = {}

M_aliases = ["M", "MTH", "MONTH", "MONTHLY"]
B_aliases = ["B", "BUS", "BUSINESS", "BUSINESSLY", 'WEEKDAY']
B_aliases = ["B", "BUS", "BUSINESS", "BUSINESSLY", "WEEKDAY"]
D_aliases = ["D", "DAY", "DLY", "DAILY"]
H_aliases = ["H", "HR", "HOUR", "HRLY", "HOURLY"]
T_aliases = ["T", "MIN", "MINUTE", "MINUTELY"]
Expand All @@ -705,7 +706,7 @@ def _period_alias_dictionary():
alias_dict[k] = 'H'

for k in T_aliases:
alias_dict[k] = 'Min'
alias_dict[k] = 'T'

for k in S_aliases:
alias_dict[k] = 'S'
Expand Down
41 changes: 41 additions & 0 deletions pandas/tseries/tests/test_frequencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,47 @@ def test_get_rule_month():
assert (result == 'MAY')


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('Q') == 2000)
assert (frequencies._period_str_to_code('Q-DEC') == 2000)
assert (frequencies._period_str_to_code('Q-FEB') == 2002)

def _assert_depr(freq, expected, aliases):
assert isinstance(aliases, list)
assert (frequencies._period_str_to_code(freq) == expected)

for alias in aliases:
with tm.assert_produces_warning(FutureWarning,
check_stacklevel=False):
assert (frequencies._period_str_to_code(alias) == expected)

_assert_depr("M", 3000, ["MTH", "MONTH", "MONTHLY"])

assert (frequencies._period_str_to_code('W') == 4000)
assert (frequencies._period_str_to_code('W-SUN') == 4000)
assert (frequencies._period_str_to_code('W-FRI') == 4005)

_assert_depr("B", 5000, ["BUS", "BUSINESS", "BUSINESSLY", "WEEKDAY"])
_assert_depr("D", 6000, ["DAY", "DLY", "DAILY"])
_assert_depr("H", 7000, ["HR", "HOUR", "HRLY", "HOURLY"])

_assert_depr("T", 8000, ["minute", "MINUTE", "MINUTELY"])
assert (frequencies._period_str_to_code('Min') == 8000)

_assert_depr("S", 9000, ["sec", "SEC", "SECOND", "SECONDLY"])
_assert_depr("L", 10000, ["MILLISECOND", "MILLISECONDLY"])
assert (frequencies._period_str_to_code('ms') == 10000)

_assert_depr("U", 11000, ["MICROSECOND", "MICROSECONDLY"])
assert (frequencies._period_str_to_code('US') == 11000)

_assert_depr("N", 12000, ["NANOSECOND", "NANOSECONDLY"])
assert (frequencies._period_str_to_code('NS') == 12000)


class TestFrequencyCode(tm.TestCase):
def test_freq_code(self):
self.assertEqual(frequencies.get_freq('A'), 1000)
Expand Down
22 changes: 19 additions & 3 deletions pandas/tseries/tests/test_period.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import pandas as pd
import numpy as np
from numpy.random import randn
from pandas.compat import range, lrange, lmap, zip, text_type, PY3
from pandas.compat import range, lrange, lmap, zip, text_type, PY3, iteritems
from pandas.compat.numpy_compat import np_datetime64_compat

from pandas import (Series, DataFrame,
Expand All @@ -36,8 +36,6 @@
class TestPeriodProperties(tm.TestCase):
"Test properties such as year, month, weekday, etc...."

#

def test_quarterly_negative_ordinals(self):
p = Period(ordinal=-1, freq='Q-DEC')
self.assertEqual(p.year, 1969)
Expand Down Expand Up @@ -440,6 +438,24 @@ def test_freq_str(self):
self.assertEqual(i1.freq, offsets.Minute())
self.assertEqual(i1.freqstr, 'T')

def test_period_deprecated_freq(self):
cases = {"M": ["MTH", "MONTH", "MONTHLY", "Mth", "month", "monthly"],
"B": ["BUS", "BUSINESS", "BUSINESSLY", "WEEKDAY", "bus"],
"D": ["DAY", "DLY", "DAILY", "Day", "Dly", "Daily"],
"H": ["HR", "HOUR", "HRLY", "HOURLY", "hr", "Hour", "HRly"],
"T": ["minute", "MINUTE", "MINUTELY", "minutely"],
"S": ["sec", "SEC", "SECOND", "SECONDLY", "second"],
"L": ["MILLISECOND", "MILLISECONDLY", "millisecond"],
"U": ["MICROSECOND", "MICROSECONDLY", "microsecond"],
"N": ["NANOSECOND", "NANOSECONDLY", "nanosecond"]}
for exp, freqs in iteritems(cases):
for freq in freqs:

with tm.assert_produces_warning(FutureWarning,
check_stacklevel=False):
res = pd.Period('2016-03-01 09:00', freq=freq)
self.assertEqual(res, Period('2016-03-01 09:00', freq=exp))

def test_repr(self):
p = Period('Jan-2000')
self.assertIn('2000-01', repr(p))
Expand Down

0 comments on commit 4da9b15

Please sign in to comment.