Skip to content

REF: implement periods_per_day #46462

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
Mar 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 3 additions & 0 deletions pandas/_libs/tslibs/dtypes.pxd
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from numpy cimport int64_t

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

Expand Down
30 changes: 30 additions & 0 deletions pandas/_libs/tslibs/dtypes.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
26 changes: 10 additions & 16 deletions pandas/_libs/tslibs/vectorized.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand Down