From b3c5ba9add1f80fbeceae6e3d0c263c6e225a1df Mon Sep 17 00:00:00 2001 From: Brock Date: Mon, 21 Mar 2022 12:53:18 -0700 Subject: [PATCH 1/2] REF: implement periods_per_day --- pandas/_libs/tslibs/dtypes.pxd | 1 + pandas/_libs/tslibs/dtypes.pyx | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/pandas/_libs/tslibs/dtypes.pxd b/pandas/_libs/tslibs/dtypes.pxd index 3686ee216b546..5235573e28250 100644 --- a/pandas/_libs/tslibs/dtypes.pxd +++ b/pandas/_libs/tslibs/dtypes.pxd @@ -3,6 +3,7 @@ from pandas._libs.tslibs.np_datetime cimport NPY_DATETIMEUNIT cdef str npy_unit_to_abbrev(NPY_DATETIMEUNIT unit) cdef NPY_DATETIMEUNIT freq_group_code_to_npy_unit(int freq) nogil +cdef int64_t periods_per_day(NPY_DATETIMEUNIT reso=*) cdef dict attrname_to_abbrevs diff --git a/pandas/_libs/tslibs/dtypes.pyx b/pandas/_libs/tslibs/dtypes.pyx index 02b78cfa530c9..48a06b2c01ae4 100644 --- a/pandas/_libs/tslibs/dtypes.pyx +++ b/pandas/_libs/tslibs/dtypes.pyx @@ -307,6 +307,36 @@ cdef NPY_DATETIMEUNIT freq_group_code_to_npy_unit(int freq) nogil: return NPY_DATETIMEUNIT.NPY_FR_D +cdef int64_t periods_per_day(NPY_DATETIMEUNIT reso=NPY_DATETIMEUNIT.NPY_FR_ns): + """ + How many of the given time units fit into a single day? + """ + cdef: + int64_t day_units + + if reso == NPY_DATETIMEUNIT.NPY_FR_ps: + # pico is the smallest unit for which we don't overflow, so + # we exclude fempto and atto + day_units = 24 * 3600 * 1_000_000_000_000 + elif reso == NPY_DATETIMEUNIT.NPY_FR_ns: + day_units = 24 * 3600 * 1_000_000_000 + elif reso == NPY_DATETIMEUNIT.NPY_FR_us: + day_units = 24 * 3600 * 1_000_000 + elif reso == NPY_DATETIMEUNIT.NPY_FR_ms: + day_units = 24 * 3600 * 1_000 + elif reso == NPY_DATETIMEUNIT.NPY_FR_s: + day_units = 24 * 3600 + elif reso == NPY_DATETIMEUNIT.NPY_FR_m: + day_units = 24 * 60 + elif reso == NPY_DATETIMEUNIT.NPY_FR_h: + day_units = 24 + elif reso == NPY_DATETIMEUNIT.NPY_FR_D: + day_units = 1 + else: + raise NotImplementedError(reso) + return day_units + + cdef dict _reso_str_map = { Resolution.RESO_NS.value: "nanosecond", Resolution.RESO_US.value: "microsecond", From bbc506bfd3451fe6a33cc6a81ce3134357b1c91c Mon Sep 17 00:00:00 2001 From: Brock Date: Mon, 21 Mar 2022 13:56:50 -0700 Subject: [PATCH 2/2] CLN: avoid denining duplicate constants --- pandas/_libs/tslibs/dtypes.pxd | 2 ++ pandas/_libs/tslibs/vectorized.pyx | 26 ++++++++++---------------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/pandas/_libs/tslibs/dtypes.pxd b/pandas/_libs/tslibs/dtypes.pxd index 5235573e28250..f61409fc16653 100644 --- a/pandas/_libs/tslibs/dtypes.pxd +++ b/pandas/_libs/tslibs/dtypes.pxd @@ -1,3 +1,5 @@ +from numpy cimport int64_t + from pandas._libs.tslibs.np_datetime cimport NPY_DATETIMEUNIT diff --git a/pandas/_libs/tslibs/vectorized.pyx b/pandas/_libs/tslibs/vectorized.pyx index 9849bbce8c564..07121396df4a2 100644 --- a/pandas/_libs/tslibs/vectorized.pyx +++ b/pandas/_libs/tslibs/vectorized.pyx @@ -21,7 +21,9 @@ cnp.import_array() from .conversion cimport normalize_i8_stamp from .dtypes import Resolution + from .ccalendar cimport DAY_NANOS +from .dtypes cimport c_Resolution from .nattype cimport ( NPY_NAT, c_NaT as NaT, @@ -168,27 +170,19 @@ def ints_to_pydatetime( # ------------------------------------------------------------------------- -cdef: - int RESO_US = Resolution.RESO_US.value - int RESO_MS = Resolution.RESO_MS.value - int RESO_SEC = Resolution.RESO_SEC.value - int RESO_MIN = Resolution.RESO_MIN.value - int RESO_HR = Resolution.RESO_HR.value - int RESO_DAY = Resolution.RESO_DAY.value - -cdef inline int _reso_stamp(npy_datetimestruct *dts): +cdef inline c_Resolution _reso_stamp(npy_datetimestruct *dts): if dts.us != 0: if dts.us % 1000 == 0: - return RESO_MS - return RESO_US + return c_Resolution.RESO_MS + return c_Resolution.RESO_US elif dts.sec != 0: - return RESO_SEC + return c_Resolution.RESO_SEC elif dts.min != 0: - return RESO_MIN + return c_Resolution.RESO_MIN elif dts.hour != 0: - return RESO_HR - return RESO_DAY + return c_Resolution.RESO_HR + return c_Resolution.RESO_DAY @cython.wraparound(False) @@ -205,7 +199,7 @@ def get_resolution(const int64_t[:] stamps, tzinfo tz=None) -> Resolution: str typ npy_datetimestruct dts - int reso = RESO_DAY, curr_reso + c_Resolution reso = c_Resolution.RESO_DAY, curr_reso if is_utc(tz) or tz is None: use_utc = True