Skip to content

Commit 2ff1d0a

Browse files
authored
REF: de-duplicate get_conversion_factor (#47770)
* REF: move get_conversion_factor to np_datetime * de-duplicate
1 parent 2d6e0b2 commit 2ff1d0a

File tree

6 files changed

+51
-81
lines changed

6 files changed

+51
-81
lines changed

pandas/_libs/tslibs/dtypes.pxd

-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ cdef NPY_DATETIMEUNIT abbrev_to_npy_unit(str abbrev)
88
cdef NPY_DATETIMEUNIT freq_group_code_to_npy_unit(int freq) nogil
99
cpdef int64_t periods_per_day(NPY_DATETIMEUNIT reso=*) except? -1
1010
cpdef int64_t periods_per_second(NPY_DATETIMEUNIT reso) except? -1
11-
cdef int64_t get_conversion_factor(NPY_DATETIMEUNIT from_unit, NPY_DATETIMEUNIT to_unit) except? -1
1211

1312
cdef dict attrname_to_abbrevs
1413

pandas/_libs/tslibs/dtypes.pyx

+6-75
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ cimport cython
44

55
from enum import Enum
66

7-
from pandas._libs.tslibs.np_datetime cimport NPY_DATETIMEUNIT
7+
from pandas._libs.tslibs.np_datetime cimport (
8+
NPY_DATETIMEUNIT,
9+
get_conversion_factor,
10+
)
811

912

1013
cdef class PeriodDtypeBase:
@@ -386,83 +389,11 @@ cpdef int64_t periods_per_day(NPY_DATETIMEUNIT reso=NPY_DATETIMEUNIT.NPY_FR_ns)
386389
"""
387390
How many of the given time units fit into a single day?
388391
"""
389-
cdef:
390-
int64_t day_units
391-
392-
if reso == NPY_DATETIMEUNIT.NPY_FR_ps:
393-
# pico is the smallest unit for which we don't overflow, so
394-
# we exclude femto and atto
395-
day_units = 24 * 3600 * 1_000_000_000_000
396-
elif reso == NPY_DATETIMEUNIT.NPY_FR_ns:
397-
day_units = 24 * 3600 * 1_000_000_000
398-
elif reso == NPY_DATETIMEUNIT.NPY_FR_us:
399-
day_units = 24 * 3600 * 1_000_000
400-
elif reso == NPY_DATETIMEUNIT.NPY_FR_ms:
401-
day_units = 24 * 3600 * 1_000
402-
elif reso == NPY_DATETIMEUNIT.NPY_FR_s:
403-
day_units = 24 * 3600
404-
elif reso == NPY_DATETIMEUNIT.NPY_FR_m:
405-
day_units = 24 * 60
406-
elif reso == NPY_DATETIMEUNIT.NPY_FR_h:
407-
day_units = 24
408-
elif reso == NPY_DATETIMEUNIT.NPY_FR_D:
409-
day_units = 1
410-
else:
411-
raise NotImplementedError(reso)
412-
return day_units
392+
return get_conversion_factor(NPY_DATETIMEUNIT.NPY_FR_D, reso)
413393

414394

415395
cpdef int64_t periods_per_second(NPY_DATETIMEUNIT reso) except? -1:
416-
if reso == NPY_DATETIMEUNIT.NPY_FR_ns:
417-
return 1_000_000_000
418-
elif reso == NPY_DATETIMEUNIT.NPY_FR_us:
419-
return 1_000_000
420-
elif reso == NPY_DATETIMEUNIT.NPY_FR_ms:
421-
return 1_000
422-
elif reso == NPY_DATETIMEUNIT.NPY_FR_s:
423-
return 1
424-
else:
425-
raise NotImplementedError(reso)
426-
427-
428-
@cython.overflowcheck(True)
429-
cdef int64_t get_conversion_factor(NPY_DATETIMEUNIT from_unit, NPY_DATETIMEUNIT to_unit) except? -1:
430-
"""
431-
Find the factor by which we need to multiply to convert from from_unit to to_unit.
432-
"""
433-
if (
434-
from_unit == NPY_DATETIMEUNIT.NPY_FR_GENERIC
435-
or to_unit == NPY_DATETIMEUNIT.NPY_FR_GENERIC
436-
):
437-
raise ValueError("unit-less resolutions are not supported")
438-
if from_unit > to_unit:
439-
raise ValueError
440-
441-
if from_unit == to_unit:
442-
return 1
443-
444-
if from_unit == NPY_DATETIMEUNIT.NPY_FR_W:
445-
return 7 * get_conversion_factor(NPY_DATETIMEUNIT.NPY_FR_D, to_unit)
446-
elif from_unit == NPY_DATETIMEUNIT.NPY_FR_D:
447-
return 24 * get_conversion_factor(NPY_DATETIMEUNIT.NPY_FR_h, to_unit)
448-
elif from_unit == NPY_DATETIMEUNIT.NPY_FR_h:
449-
return 60 * get_conversion_factor(NPY_DATETIMEUNIT.NPY_FR_m, to_unit)
450-
elif from_unit == NPY_DATETIMEUNIT.NPY_FR_m:
451-
return 60 * get_conversion_factor(NPY_DATETIMEUNIT.NPY_FR_s, to_unit)
452-
elif from_unit == NPY_DATETIMEUNIT.NPY_FR_s:
453-
return 1000 * get_conversion_factor(NPY_DATETIMEUNIT.NPY_FR_ms, to_unit)
454-
elif from_unit == NPY_DATETIMEUNIT.NPY_FR_ms:
455-
return 1000 * get_conversion_factor(NPY_DATETIMEUNIT.NPY_FR_us, to_unit)
456-
elif from_unit == NPY_DATETIMEUNIT.NPY_FR_us:
457-
return 1000 * get_conversion_factor(NPY_DATETIMEUNIT.NPY_FR_ns, to_unit)
458-
elif from_unit == NPY_DATETIMEUNIT.NPY_FR_ns:
459-
return 1000 * get_conversion_factor(NPY_DATETIMEUNIT.NPY_FR_ps, to_unit)
460-
elif from_unit == NPY_DATETIMEUNIT.NPY_FR_ps:
461-
return 1000 * get_conversion_factor(NPY_DATETIMEUNIT.NPY_FR_fs, to_unit)
462-
elif from_unit == NPY_DATETIMEUNIT.NPY_FR_fs:
463-
return 1000 * get_conversion_factor(NPY_DATETIMEUNIT.NPY_FR_as, to_unit)
464-
else:
465-
raise ValueError(from_unit, to_unit)
396+
return get_conversion_factor(NPY_DATETIMEUNIT.NPY_FR_s, reso)
466397

467398

468399
cdef dict _reso_str_map = {

pandas/_libs/tslibs/np_datetime.pxd

+1
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ cpdef cnp.ndarray astype_overflowsafe(
102102
cnp.dtype dtype, # ndarray[datetime64[anyunit]]
103103
bint copy=*,
104104
)
105+
cdef int64_t get_conversion_factor(NPY_DATETIMEUNIT from_unit, NPY_DATETIMEUNIT to_unit) except? -1
105106

106107
cdef bint cmp_dtstructs(npy_datetimestruct* left, npy_datetimestruct* right, int op)
107108
cdef get_implementation_bounds(

pandas/_libs/tslibs/np_datetime.pyx

+41
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
cimport cython
12
from cpython.datetime cimport (
23
PyDateTime_DATE_GET_HOUR,
34
PyDateTime_DATE_GET_MICROSECOND,
@@ -450,3 +451,43 @@ cdef int op_to_op_code(op):
450451
return Py_GE
451452
if op is operator.gt:
452453
return Py_GT
454+
455+
456+
@cython.overflowcheck(True)
457+
cdef int64_t get_conversion_factor(NPY_DATETIMEUNIT from_unit, NPY_DATETIMEUNIT to_unit) except? -1:
458+
"""
459+
Find the factor by which we need to multiply to convert from from_unit to to_unit.
460+
"""
461+
if (
462+
from_unit == NPY_DATETIMEUNIT.NPY_FR_GENERIC
463+
or to_unit == NPY_DATETIMEUNIT.NPY_FR_GENERIC
464+
):
465+
raise ValueError("unit-less resolutions are not supported")
466+
if from_unit > to_unit:
467+
raise ValueError
468+
469+
if from_unit == to_unit:
470+
return 1
471+
472+
if from_unit == NPY_DATETIMEUNIT.NPY_FR_W:
473+
return 7 * get_conversion_factor(NPY_DATETIMEUNIT.NPY_FR_D, to_unit)
474+
elif from_unit == NPY_DATETIMEUNIT.NPY_FR_D:
475+
return 24 * get_conversion_factor(NPY_DATETIMEUNIT.NPY_FR_h, to_unit)
476+
elif from_unit == NPY_DATETIMEUNIT.NPY_FR_h:
477+
return 60 * get_conversion_factor(NPY_DATETIMEUNIT.NPY_FR_m, to_unit)
478+
elif from_unit == NPY_DATETIMEUNIT.NPY_FR_m:
479+
return 60 * get_conversion_factor(NPY_DATETIMEUNIT.NPY_FR_s, to_unit)
480+
elif from_unit == NPY_DATETIMEUNIT.NPY_FR_s:
481+
return 1000 * get_conversion_factor(NPY_DATETIMEUNIT.NPY_FR_ms, to_unit)
482+
elif from_unit == NPY_DATETIMEUNIT.NPY_FR_ms:
483+
return 1000 * get_conversion_factor(NPY_DATETIMEUNIT.NPY_FR_us, to_unit)
484+
elif from_unit == NPY_DATETIMEUNIT.NPY_FR_us:
485+
return 1000 * get_conversion_factor(NPY_DATETIMEUNIT.NPY_FR_ns, to_unit)
486+
elif from_unit == NPY_DATETIMEUNIT.NPY_FR_ns:
487+
return 1000 * get_conversion_factor(NPY_DATETIMEUNIT.NPY_FR_ps, to_unit)
488+
elif from_unit == NPY_DATETIMEUNIT.NPY_FR_ps:
489+
return 1000 * get_conversion_factor(NPY_DATETIMEUNIT.NPY_FR_fs, to_unit)
490+
elif from_unit == NPY_DATETIMEUNIT.NPY_FR_fs:
491+
return 1000 * get_conversion_factor(NPY_DATETIMEUNIT.NPY_FR_as, to_unit)
492+
else:
493+
raise ValueError(from_unit, to_unit)

pandas/_libs/tslibs/timedeltas.pyx

+2-4
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,7 @@ from pandas._libs.tslibs.conversion cimport (
3535
cast_from_unit,
3636
precision_from_unit,
3737
)
38-
from pandas._libs.tslibs.dtypes cimport (
39-
get_conversion_factor,
40-
npy_unit_to_abbrev,
41-
)
38+
from pandas._libs.tslibs.dtypes cimport npy_unit_to_abbrev
4239
from pandas._libs.tslibs.nattype cimport (
4340
NPY_NAT,
4441
c_NaT as NaT,
@@ -50,6 +47,7 @@ from pandas._libs.tslibs.np_datetime cimport (
5047
NPY_FR_ns,
5148
cmp_dtstructs,
5249
cmp_scalar,
50+
get_conversion_factor,
5351
get_datetime64_unit,
5452
get_timedelta64_value,
5553
get_unit_from_dtype,

pandas/_libs/tslibs/timestamps.pyx

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ from pandas._libs.tslibs.conversion cimport (
5454
maybe_localize_tso,
5555
)
5656
from pandas._libs.tslibs.dtypes cimport (
57-
get_conversion_factor,
5857
npy_unit_to_abbrev,
5958
periods_per_day,
6059
periods_per_second,
@@ -83,6 +82,7 @@ from pandas._libs.tslibs.np_datetime cimport (
8382
NPY_FR_ns,
8483
cmp_dtstructs,
8584
cmp_scalar,
85+
get_conversion_factor,
8686
get_datetime64_unit,
8787
get_datetime64_value,
8888
get_unit_from_dtype,

0 commit comments

Comments
 (0)