1
1
# period frequency constants corresponding to scikits timeseries
2
2
# originals
3
+ from enum import Enum
3
4
4
5
5
6
cdef class PeriodDtypeBase:
@@ -112,6 +113,9 @@ _period_code_map.update({
112
113
" C" : 5000 , # Custom Business Day
113
114
})
114
115
116
+ cdef set _month_names = {
117
+ x.split(" -" )[- 1 ] for x in _period_code_map.keys() if x.startswith(" A-" )
118
+ }
115
119
116
120
# Map attribute-name resolutions to resolution abbreviations
117
121
_attrname_to_abbrevs = {
@@ -127,6 +131,7 @@ _attrname_to_abbrevs = {
127
131
" nanosecond" : " N" ,
128
132
}
129
133
cdef dict attrname_to_abbrevs = _attrname_to_abbrevs
134
+ cdef dict _abbrev_to_attrnames = {v: k for k, v in attrname_to_abbrevs.items()}
130
135
131
136
132
137
class FreqGroup :
@@ -149,3 +154,124 @@ class FreqGroup:
149
154
def get_freq_group (code: int ) -> int:
150
155
# See also: PeriodDtypeBase.freq_group
151
156
return (code // 1000) * 1000
157
+
158
+
159
+ class Resolution(Enum ):
160
+
161
+ # Note: cython won't allow us to reference the cdef versions at the
162
+ # module level
163
+ RESO_NS = 0
164
+ RESO_US = 1
165
+ RESO_MS = 2
166
+ RESO_SEC = 3
167
+ RESO_MIN = 4
168
+ RESO_HR = 5
169
+ RESO_DAY = 6
170
+ RESO_MTH = 7
171
+ RESO_QTR = 8
172
+ RESO_YR = 9
173
+
174
+ def __lt__ (self , other ):
175
+ return self .value < other.value
176
+
177
+ def __ge__ (self , other ):
178
+ return self .value >= other.value
179
+
180
+ @property
181
+ def freq_group (self ):
182
+ # TODO: annotate as returning FreqGroup once that is an enum
183
+ if self == Resolution.RESO_NS:
184
+ return FreqGroup.FR_NS
185
+ elif self == Resolution.RESO_US:
186
+ return FreqGroup.FR_US
187
+ elif self == Resolution.RESO_MS:
188
+ return FreqGroup.FR_MS
189
+ elif self == Resolution.RESO_SEC:
190
+ return FreqGroup.FR_SEC
191
+ elif self == Resolution.RESO_MIN:
192
+ return FreqGroup.FR_MIN
193
+ elif self == Resolution.RESO_HR:
194
+ return FreqGroup.FR_HR
195
+ elif self == Resolution.RESO_DAY:
196
+ return FreqGroup.FR_DAY
197
+ elif self == Resolution.RESO_MTH:
198
+ return FreqGroup.FR_MTH
199
+ elif self == Resolution.RESO_QTR:
200
+ return FreqGroup.FR_QTR
201
+ elif self == Resolution.RESO_YR:
202
+ return FreqGroup.FR_ANN
203
+ else :
204
+ raise ValueError (self )
205
+
206
+ @property
207
+ def attrname (self ) -> str:
208
+ """
209
+ Return datetime attribute name corresponding to this Resolution.
210
+
211
+ Examples
212
+ --------
213
+ >>> Resolution.RESO_SEC.attrname
214
+ 'second'
215
+ """
216
+ return _reso_str_map[self.value]
217
+
218
+ @classmethod
219
+ def from_attrname(cls , attrname: str ) -> "Resolution":
220
+ """
221
+ Return resolution str against resolution code.
222
+
223
+ Examples
224
+ --------
225
+ >>> Resolution.from_attrname('second')
226
+ 2
227
+
228
+ >>> Resolution.from_attrname('second') == Resolution.RESO_SEC
229
+ True
230
+ """
231
+ return cls(_str_reso_map[attrname])
232
+
233
+ @classmethod
234
+ def get_reso_from_freq(cls , freq: str ) -> "Resolution":
235
+ """
236
+ Return resolution code against frequency str.
237
+
238
+ `freq` is given by the `offset.freqstr` for some DateOffset object.
239
+
240
+ Examples
241
+ --------
242
+ >>> Resolution.get_reso_from_freq('H')
243
+ 4
244
+
245
+ >>> Resolution.get_reso_from_freq('H') == Resolution.RESO_HR
246
+ True
247
+ """
248
+ try:
249
+ attr_name = _abbrev_to_attrnames[freq]
250
+ except KeyError:
251
+ # For quarterly and yearly resolutions , we need to chop off
252
+ # a month string.
253
+ split_freq = freq.split(" -" )
254
+ if len(split_freq ) != 2:
255
+ raise
256
+ if split_freq[1] not in _month_names:
257
+ # i.e. we want e.g. "Q-DEC", not "Q-INVALID"
258
+ raise
259
+ attr_name = _abbrev_to_attrnames[split_freq[0 ]]
260
+
261
+ return cls.from_attrname(attr_name )
262
+
263
+
264
+ cdef dict _reso_str_map = {
265
+ Resolution.RESO_NS.value: " nanosecond" ,
266
+ Resolution.RESO_US.value: " microsecond" ,
267
+ Resolution.RESO_MS.value: " millisecond" ,
268
+ Resolution.RESO_SEC.value: " second" ,
269
+ Resolution.RESO_MIN.value: " minute" ,
270
+ Resolution.RESO_HR.value: " hour" ,
271
+ Resolution.RESO_DAY.value: " day" ,
272
+ Resolution.RESO_MTH.value: " month" ,
273
+ Resolution.RESO_QTR.value: " quarter" ,
274
+ Resolution.RESO_YR.value: " year" ,
275
+ }
276
+
277
+ cdef dict _str_reso_map = {v: k for k, v in _reso_str_map.items()}
0 commit comments