Skip to content

REF: implement c_FreqGroup, FreqGroup in tslibs.dtypes #34588

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

Merged
merged 2 commits into from
Jun 8, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
17 changes: 17 additions & 0 deletions pandas/_libs/tslibs/dtypes.pxd
Original file line number Diff line number Diff line change
@@ -1,4 +1,21 @@

cdef enum c_FreqGroup:
# Mirrors FreqGroup in the .pxy file
FR_ANN = 1000
FR_QTR = 2000
FR_MTH = 3000
FR_WK = 4000
FR_BUS = 5000
FR_DAY = 6000
FR_HR = 7000
FR_MIN = 8000
FR_SEC = 9000
FR_MS = 10000
FR_US = 11000
FR_NS = 12000
FR_UND = -10000 # undefined


cdef enum PeriodDtypeCode:
# Annual freqs with various fiscal year ends.
# eg, 2005 for A_FEB runs Mar 1, 2004 to Feb 28, 2005
Expand Down
17 changes: 17 additions & 0 deletions pandas/_libs/tslibs/dtypes.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,20 @@ _period_code_map.update({
"W": 4000, # Weekly
"C": 5000, # Custom Business Day
})


class FreqGroup:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe overlooking something simple but do we need both or does the enum alone suffice?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the one in the .pxd we can't access from python-space

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also i expect before long we'll make this one into class FreqGroup(Enum) to de-duplicate it with Resolution

# Mirrors c_FreqGroup in the .pxd file
FR_ANN = 1000
FR_QTR = 2000
FR_MTH = 3000
FR_WK = 4000
FR_BUS = 5000
FR_DAY = 6000
FR_HR = 7000
FR_MIN = 8000
FR_SEC = 9000
FR_MS = 10000
FR_US = 11000
FR_NS = 12000
FR_UND = -10000 # undefined
17 changes: 1 addition & 16 deletions pandas/_libs/tslibs/frequencies.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,12 @@ from pandas._libs.tslibs.offsets import (
opattern,
)

from .dtypes import _period_code_map, _reverse_period_code_map
from .dtypes import FreqGroup, _period_code_map, _reverse_period_code_map

# ---------------------------------------------------------------------
# Period codes


class FreqGroup:
FR_ANN = 1000
FR_QTR = 2000
FR_MTH = 3000
FR_WK = 4000
FR_BUS = 5000
FR_DAY = 6000
FR_HR = 7000
FR_MIN = 8000
FR_SEC = 9000
FR_MS = 10000
FR_US = 11000
FR_NS = 12000


# Map attribute-name resolutions to resolution abbreviations
_attrname_to_abbrevs = {
"year": "A",
Expand Down
77 changes: 30 additions & 47 deletions pandas/_libs/tslibs/period.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,22 @@ from pandas._libs.tslibs.ccalendar cimport (
)
from pandas._libs.tslibs.ccalendar cimport c_MONTH_NUMBERS

from pandas._libs.tslibs.dtypes cimport PeriodPseudoDtype
from pandas._libs.tslibs.dtypes cimport (
PeriodPseudoDtype,
FR_UND,
FR_ANN,
FR_QTR,
FR_MTH,
FR_WK,
FR_BUS,
FR_DAY,
FR_HR,
FR_MIN,
FR_SEC,
FR_MS,
FR_US,
FR_NS,
)

from pandas._libs.tslibs.frequencies cimport (
attrname_to_abbrevs,
Expand Down Expand Up @@ -98,23 +113,6 @@ ctypedef int64_t (*freq_conv_func)(int64_t, asfreq_info*) nogil

cdef extern from *:
"""
/*** FREQUENCY CONSTANTS ***/
// See frequencies.pyx for more detailed variants

#define FR_ANN 1000 /* Annual */
#define FR_QTR 2000 /* Quarterly - December year end (default Q) */
#define FR_MTH 3000 /* Monthly */
#define FR_WK 4000 /* Weekly */
#define FR_BUS 5000 /* Business days */
#define FR_DAY 6000 /* Daily */
#define FR_HR 7000 /* Hourly */
#define FR_MIN 8000 /* Minutely */
#define FR_SEC 9000 /* Secondly */
#define FR_MS 10000 /* Millisecondly */
#define FR_US 11000 /* Microsecondly */
#define FR_NS 12000 /* Nanosecondly */
#define FR_UND -10000 /* Undefined */

// must use npy typedef b/c int64_t is aliased in cython-generated c
// unclear why we need LL for that row.
// see https://github.com/pandas-dev/pandas/pull/34416/
Expand All @@ -128,20 +126,6 @@ cdef extern from *:
{0, 0, 0, 0, 0, 0, 1}};
"""
int64_t daytime_conversion_factor_matrix[7][7]
# TODO: Can we get these frequencies from frequencies.FreqGroup?
int FR_ANN
int FR_QTR
int FR_MTH
int FR_WK
int FR_DAY
int FR_HR
int FR_MIN
int FR_SEC
int FR_MS
int FR_US
int FR_NS
int FR_BUS
int FR_UND


cdef int max_value(int left, int right) nogil:
Expand Down Expand Up @@ -1162,30 +1146,29 @@ cdef str period_format(int64_t value, int freq, object fmt=None):

if fmt is None:
freq_group = get_freq_group(freq)
if freq_group == 1000: # FR_ANN
if freq_group == FR_ANN:
fmt = b'%Y'
elif freq_group == 2000: # FR_QTR
elif freq_group == FR_QTR:
fmt = b'%FQ%q'
elif freq_group == 3000: # FR_MTH
elif freq_group == FR_MTH:
fmt = b'%Y-%m'
elif freq_group == 4000: # WK
left = period_asfreq(value, freq, 6000, 0)
right = period_asfreq(value, freq, 6000, 1)
return f"{period_format(left, 6000)}/{period_format(right, 6000)}"
elif (freq_group == 5000 # BUS
or freq_group == 6000): # DAY
elif freq_group == FR_WK:
left = period_asfreq(value, freq, FR_DAY, 0)
right = period_asfreq(value, freq, FR_DAY, 1)
return f"{period_format(left, FR_DAY)}/{period_format(right, FR_DAY)}"
elif freq_group == FR_BUS or freq_group == FR_DAY:
fmt = b'%Y-%m-%d'
elif freq_group == 7000: # HR
elif freq_group == FR_HR:
fmt = b'%Y-%m-%d %H:00'
elif freq_group == 8000: # MIN
elif freq_group == FR_MIN:
fmt = b'%Y-%m-%d %H:%M'
elif freq_group == 9000: # SEC
elif freq_group == FR_SEC:
fmt = b'%Y-%m-%d %H:%M:%S'
elif freq_group == 10000: # MILLISEC
elif freq_group == FR_MS:
fmt = b'%Y-%m-%d %H:%M:%S.%l'
elif freq_group == 11000: # MICROSEC
elif freq_group == FR_US:
fmt = b'%Y-%m-%d %H:%M:%S.%u'
elif freq_group == 12000: # NANOSEC
elif freq_group == FR_NS:
fmt = b'%Y-%m-%d %H:%M:%S.%n'
else:
raise ValueError(f"Unknown freq: {freq}")
Expand Down