From 2aa8a8f351c63226062152c9e0470fa28eef73a3 Mon Sep 17 00:00:00 2001 From: Brock Date: Thu, 16 Jun 2022 19:17:10 -0700 Subject: [PATCH] implement abbrev_to_npy_unit --- pandas/_libs/tslibs/conversion.pyx | 26 +++++++++++++---------- pandas/_libs/tslibs/dtypes.pxd | 1 + pandas/_libs/tslibs/dtypes.pyx | 33 ++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/pandas/_libs/tslibs/conversion.pyx b/pandas/_libs/tslibs/conversion.pyx index 6cbc06830471e..fb77e2b5f3a0c 100644 --- a/pandas/_libs/tslibs/conversion.pyx +++ b/pandas/_libs/tslibs/conversion.pyx @@ -31,7 +31,10 @@ from cpython.datetime cimport ( import_datetime() from pandas._libs.tslibs.base cimport ABCTimestamp -from pandas._libs.tslibs.dtypes cimport periods_per_second +from pandas._libs.tslibs.dtypes cimport ( + abbrev_to_npy_unit, + periods_per_second, +) from pandas._libs.tslibs.np_datetime cimport ( NPY_DATETIMEUNIT, NPY_FR_ns, @@ -139,35 +142,36 @@ cpdef inline (int64_t, int) precision_from_unit(str unit): cdef: int64_t m int p + NPY_DATETIMEUNIT reso = abbrev_to_npy_unit(unit) - if unit == "Y": + if reso == NPY_DATETIMEUNIT.NPY_FR_Y: m = 1_000_000_000 * 31556952 p = 9 - elif unit == "M": + elif reso == NPY_DATETIMEUNIT.NPY_FR_M: m = 1_000_000_000 * 2629746 p = 9 - elif unit == "W": + elif reso == NPY_DATETIMEUNIT.NPY_FR_W: m = 1_000_000_000 * 3600 * 24 * 7 p = 9 - elif unit == "D" or unit == "d": + elif reso == NPY_DATETIMEUNIT.NPY_FR_D: m = 1_000_000_000 * 3600 * 24 p = 9 - elif unit == "h": + elif reso == NPY_DATETIMEUNIT.NPY_FR_h: m = 1_000_000_000 * 3600 p = 9 - elif unit == "m": + elif reso == NPY_DATETIMEUNIT.NPY_FR_m: m = 1_000_000_000 * 60 p = 9 - elif unit == "s": + elif reso == NPY_DATETIMEUNIT.NPY_FR_s: m = 1_000_000_000 p = 9 - elif unit == "ms": + elif reso == NPY_DATETIMEUNIT.NPY_FR_ms: m = 1_000_000 p = 6 - elif unit == "us": + elif reso == NPY_DATETIMEUNIT.NPY_FR_us: m = 1000 p = 3 - elif unit == "ns" or unit is None: + elif reso == NPY_DATETIMEUNIT.NPY_FR_ns or reso == NPY_DATETIMEUNIT.NPY_FR_GENERIC: m = 1 p = 0 else: diff --git a/pandas/_libs/tslibs/dtypes.pxd b/pandas/_libs/tslibs/dtypes.pxd index e16a389bc5459..dc2a1b186edcf 100644 --- a/pandas/_libs/tslibs/dtypes.pxd +++ b/pandas/_libs/tslibs/dtypes.pxd @@ -4,6 +4,7 @@ from pandas._libs.tslibs.np_datetime cimport NPY_DATETIMEUNIT cdef str npy_unit_to_abbrev(NPY_DATETIMEUNIT unit) +cdef NPY_DATETIMEUNIT abbrev_to_npy_unit(str abbrev) cdef NPY_DATETIMEUNIT freq_group_code_to_npy_unit(int freq) nogil cpdef int64_t periods_per_day(NPY_DATETIMEUNIT reso=*) except? -1 cdef int64_t periods_per_second(NPY_DATETIMEUNIT reso) except? -1 diff --git a/pandas/_libs/tslibs/dtypes.pyx b/pandas/_libs/tslibs/dtypes.pyx index f843f6ccdfc58..a340fe477e982 100644 --- a/pandas/_libs/tslibs/dtypes.pyx +++ b/pandas/_libs/tslibs/dtypes.pyx @@ -313,6 +313,39 @@ cdef str npy_unit_to_abbrev(NPY_DATETIMEUNIT unit): raise NotImplementedError(unit) +cdef NPY_DATETIMEUNIT abbrev_to_npy_unit(str abbrev): + if abbrev == "Y": + return NPY_DATETIMEUNIT.NPY_FR_Y + elif abbrev == "M": + return NPY_DATETIMEUNIT.NPY_FR_M + elif abbrev == "W": + return NPY_DATETIMEUNIT.NPY_FR_W + elif abbrev == "D" or abbrev == "d": + return NPY_DATETIMEUNIT.NPY_FR_D + elif abbrev == "h": + return NPY_DATETIMEUNIT.NPY_FR_h + elif abbrev == "m": + return NPY_DATETIMEUNIT.NPY_FR_m + elif abbrev == "s": + return NPY_DATETIMEUNIT.NPY_FR_s + elif abbrev == "ms": + return NPY_DATETIMEUNIT.NPY_FR_ms + elif abbrev == "us": + return NPY_DATETIMEUNIT.NPY_FR_us + elif abbrev == "ns": + return NPY_DATETIMEUNIT.NPY_FR_ns + elif abbrev == "ps": + return NPY_DATETIMEUNIT.NPY_FR_ps + elif abbrev == "fs": + return NPY_DATETIMEUNIT.NPY_FR_fs + elif abbrev == "as": + return NPY_DATETIMEUNIT.NPY_FR_as + elif abbrev is None: + return NPY_DATETIMEUNIT.NPY_FR_GENERIC + else: + raise ValueError(f"Unrecognized unit {abbrev}") + + cdef NPY_DATETIMEUNIT freq_group_code_to_npy_unit(int freq) nogil: """ Convert the freq to the corresponding NPY_DATETIMEUNIT to pass