Skip to content

Commit f17aa26

Browse files
jbrockmendeljreback
authored andcommitted
Implement numpy_helper functions directly in cython (#18059)
1 parent 9c49e64 commit f17aa26

File tree

5 files changed

+75
-84
lines changed

5 files changed

+75
-84
lines changed

pandas/_libs/lib.pyx

+1-2
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,8 @@ from cpython.datetime cimport (PyDateTime_Check, PyDate_Check,
4848
PyTime_Check, PyDelta_Check,
4949
PyDateTime_IMPORT)
5050
PyDateTime_IMPORT
51-
# this is our tseries.pxd
52-
from datetime cimport get_timedelta64_value, get_datetime64_value
5351

52+
from tslibs.np_datetime cimport get_timedelta64_value, get_datetime64_value
5453

5554
from tslib cimport _check_all_nulls
5655
import tslib

pandas/_libs/src/datetime.pxd

+6-57
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,20 @@
11
# cython: profile=False
2-
from numpy cimport int64_t, int32_t, npy_int64, npy_int32, ndarray
3-
from cpython cimport PyObject
2+
from numpy cimport int64_t, npy_int64, npy_int32
43

54
from cpython cimport PyUnicode_Check, PyUnicode_AsASCIIString
65

76

8-
cdef extern from "datetime.h":
9-
10-
ctypedef class datetime.date [object PyDateTime_Date]:
11-
pass
12-
13-
ctypedef class datetime.datetime [object PyDateTime_DateTime]:
14-
pass
15-
16-
ctypedef class datetime.timedelta [object PyDateTime_Delta]:
17-
pass
18-
19-
void PyDateTime_IMPORT()
20-
21-
int PyDateTime_GET_YEAR(date)
22-
int PyDateTime_GET_MONTH(date)
23-
int PyDateTime_GET_DAY(date)
24-
int PyDateTime_DATE_GET_HOUR(object o)
25-
int PyDateTime_DATE_GET_MINUTE(object o)
26-
int PyDateTime_DATE_GET_SECOND(object o)
27-
int PyDateTime_DATE_GET_MICROSECOND(object o)
28-
int PyDateTime_TIME_GET_HOUR(object o)
29-
int PyDateTime_TIME_GET_MINUTE(object o)
30-
int PyDateTime_TIME_GET_SECOND(object o)
31-
int PyDateTime_TIME_GET_MICROSECOND(object o)
32-
bint PyDateTime_Check(object o)
33-
bint PyDate_Check(object o)
34-
bint PyTime_Check(object o)
35-
bint PyDelta_Check(object o)
36-
object PyDateTime_FromDateAndTime(int year, int month, int day, int hour,
37-
int minute, int second, int us)
38-
397
cdef extern from "numpy/ndarrayobject.h":
408

419
ctypedef int64_t npy_timedelta
4210
ctypedef int64_t npy_datetime
4311

4412
ctypedef enum NPY_CASTING:
45-
NPY_NO_CASTING
46-
NPY_EQUIV_CASTING
47-
NPY_SAFE_CASTING
48-
NPY_SAME_KIND_CASTING
49-
NPY_UNSAFE_CASTING
13+
NPY_NO_CASTING
14+
NPY_EQUIV_CASTING
15+
NPY_SAFE_CASTING
16+
NPY_SAME_KIND_CASTING
17+
NPY_UNSAFE_CASTING
5018

5119

5220
cdef extern from "numpy_helper.h":
@@ -79,9 +47,6 @@ cdef extern from "datetime/np_datetime.h":
7947
npy_int64 year
8048
npy_int32 month, day, hour, min, sec, us, ps, as
8149

82-
int cmp_pandas_datetimestruct(pandas_datetimestruct *a,
83-
pandas_datetimestruct *b)
84-
8550
npy_datetime pandas_datetimestruct_to_datetime(PANDAS_DATETIMEUNIT fr,
8651
pandas_datetimestruct *d) nogil
8752
void pandas_datetime_to_datetimestruct(npy_datetime val,
@@ -102,8 +67,6 @@ cdef extern from "datetime/np_datetime_strings.h":
10267
PANDAS_DATETIMEUNIT *out_bestunit,
10368
npy_bool *out_special)
10469

105-
# int parse_python_string(object obj, pandas_datetimestruct *out) except -1
106-
10770

10871

10972

@@ -134,17 +97,3 @@ cdef inline int _cstring_to_dts(char *val, int length,
13497
NPY_UNSAFE_CASTING,
13598
dts, out_local, out_tzoffset, &out_bestunit, &special)
13699
return result
137-
138-
139-
cdef inline bint check_dts_bounds(pandas_datetimestruct *dts):
140-
"""Returns True if an error needs to be raised"""
141-
cdef:
142-
bint error = False
143-
144-
if (dts.year <= 1677 and
145-
cmp_pandas_datetimestruct(dts, &_NS_MIN_DTS) == -1):
146-
error = True
147-
elif (dts.year >= 2262 and
148-
cmp_pandas_datetimestruct(dts, &_NS_MAX_DTS) == 1):
149-
error = True
150-
return error

pandas/_libs/tslib.pyx

+4-5
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,8 @@ PyDateTime_IMPORT
4141
from datetime cimport (
4242
pandas_datetime_to_datetimestruct,
4343
days_per_month_table,
44-
get_datetime64_value,
45-
get_timedelta64_value,
46-
get_datetime64_unit,
4744
PANDAS_DATETIMEUNIT,
4845
_string_to_dts,
49-
npy_datetime,
5046
is_leapyear,
5147
dayofweek,
5248
PANDAS_FR_ns)
@@ -59,7 +55,10 @@ from tslibs.np_datetime cimport (check_dts_bounds,
5955
cmp_scalar,
6056
pandas_datetimestruct,
6157
dt64_to_dtstruct, dtstruct_to_dt64,
62-
pydatetime_to_dt64, pydate_to_dt64)
58+
pydatetime_to_dt64, pydate_to_dt64,
59+
npy_datetime,
60+
get_datetime64_unit, get_datetime64_value,
61+
get_timedelta64_value)
6362
from tslibs.np_datetime import OutOfBoundsDatetime
6463

6564
from khash cimport (

pandas/_libs/tslibs/np_datetime.pxd

+38
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,46 @@ from cpython.datetime cimport date, datetime
55

66
from numpy cimport int64_t, int32_t
77

8+
cdef extern from "numpy/ndarrayobject.h":
9+
ctypedef int64_t npy_timedelta
10+
ctypedef int64_t npy_datetime
11+
12+
cdef extern from "numpy/ndarraytypes.h":
13+
ctypedef struct PyArray_DatetimeMetaData:
14+
PANDAS_DATETIMEUNIT base
15+
int64_t num
16+
17+
cdef extern from "numpy/arrayscalars.h":
18+
ctypedef struct PyDatetimeScalarObject:
19+
# PyObject_HEAD
20+
npy_datetime obval
21+
PyArray_DatetimeMetaData obmeta
22+
23+
ctypedef struct PyTimedeltaScalarObject:
24+
# PyObject_HEAD
25+
npy_timedelta obval
26+
PyArray_DatetimeMetaData obmeta
827

928
cdef extern from "../src/datetime/np_datetime.h":
1029
ctypedef struct pandas_datetimestruct:
1130
int64_t year
1231
int32_t month, day, hour, min, sec, us, ps, as
1332

33+
ctypedef enum PANDAS_DATETIMEUNIT:
34+
PANDAS_FR_Y
35+
PANDAS_FR_M
36+
PANDAS_FR_W
37+
PANDAS_FR_D
38+
PANDAS_FR_B
39+
PANDAS_FR_h
40+
PANDAS_FR_m
41+
PANDAS_FR_s
42+
PANDAS_FR_ms
43+
PANDAS_FR_us
44+
PANDAS_FR_ns
45+
PANDAS_FR_ps
46+
PANDAS_FR_fs
47+
PANDAS_FR_as
1448

1549
cdef int reverse_ops[6]
1650

@@ -23,3 +57,7 @@ cdef void dt64_to_dtstruct(int64_t dt64, pandas_datetimestruct* out) nogil
2357

2458
cdef int64_t pydatetime_to_dt64(datetime val, pandas_datetimestruct *dts)
2559
cdef int64_t pydate_to_dt64(date val, pandas_datetimestruct *dts)
60+
61+
cdef npy_datetime get_datetime64_value(object obj) nogil
62+
cdef npy_timedelta get_timedelta64_value(object obj) nogil
63+
cdef PANDAS_DATETIMEUNIT get_datetime64_unit(object obj) nogil

pandas/_libs/tslibs/np_datetime.pyx

+26-20
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,7 @@ PyDateTime_IMPORT
1414

1515
from numpy cimport int64_t
1616

17-
cdef extern from "numpy/ndarrayobject.h":
18-
ctypedef int64_t npy_timedelta
19-
ctypedef int64_t npy_datetime
20-
2117
cdef extern from "../src/datetime/np_datetime.h":
22-
ctypedef enum PANDAS_DATETIMEUNIT:
23-
PANDAS_FR_Y
24-
PANDAS_FR_M
25-
PANDAS_FR_W
26-
PANDAS_FR_D
27-
PANDAS_FR_B
28-
PANDAS_FR_h
29-
PANDAS_FR_m
30-
PANDAS_FR_s
31-
PANDAS_FR_ms
32-
PANDAS_FR_us
33-
PANDAS_FR_ns
34-
PANDAS_FR_ps
35-
PANDAS_FR_fs
36-
PANDAS_FR_as
37-
3818
int cmp_pandas_datetimestruct(pandas_datetimestruct *a,
3919
pandas_datetimestruct *b)
4020

@@ -48,6 +28,32 @@ cdef extern from "../src/datetime/np_datetime.h":
4828

4929
pandas_datetimestruct _NS_MIN_DTS, _NS_MAX_DTS
5030

31+
# ----------------------------------------------------------------------
32+
# numpy object inspection
33+
34+
cdef inline npy_datetime get_datetime64_value(object obj) nogil:
35+
"""
36+
returns the int64 value underlying scalar numpy datetime64 object
37+
38+
Note that to interpret this as a datetime, the corresponding unit is
39+
also needed. That can be found using `get_datetime64_unit`.
40+
"""
41+
return (<PyDatetimeScalarObject*>obj).obval
42+
43+
44+
cdef inline npy_timedelta get_timedelta64_value(object obj) nogil:
45+
"""
46+
returns the int64 value underlying scalar numpy timedelta64 object
47+
"""
48+
return (<PyTimedeltaScalarObject*>obj).obval
49+
50+
51+
cdef inline PANDAS_DATETIMEUNIT get_datetime64_unit(object obj) nogil:
52+
"""
53+
returns the unit part of the dtype for a numpy datetime64 object.
54+
"""
55+
return <PANDAS_DATETIMEUNIT>(<PyDatetimeScalarObject*>obj).obmeta.base
56+
5157
# ----------------------------------------------------------------------
5258
# Comparison
5359

0 commit comments

Comments
 (0)