我正在尝试加快字符串到日期的转换。我更喜欢cython。获得c tm struct之后。我正在使用cpython.datetime.date函数将tm struct转换为python datetime。有用。加快大约50%的速度令人鼓舞。但是我的代码浪费了时间cpython.datetime.date函数。有没有更有效的方法来进行这种转换。我在下面分享我的代码。代码编写不整齐。但我希望对我要尝试做的事情有所帮助。
谢谢。
cimport cython
from cython.parallel import prange, parallel
from cpython.datetime cimport date, PyDateTime_Date
cimport numpy as np
import numpy as np
import pandas as pd
from libc.stdlib cimport atoi, malloc, free
from libc.string cimport strcpy, strncpy
from libc.stdio cimport sprintf
from cpython.datetime cimport import_datetime
import_datetime()
cdef extern from "time.h" nogil:
ctypedef long time_t
struct tm:
int tm_sec
int tm_min
int tm_hour
int tm_mday
int tm_mon
int tm_year
int tm_wday
int tm_yday
int tm_isdst
time_t mktime(tm *timeptr)
char *strptime(const char *s, const char *format, tm *tm)
@cython.boundscheck(False)
@cython.wraparound(False)
def convert_date_fast(np.int32_t[::1] date_vec):
cdef int i, d_year, d_month, d_day, t_hour, t_min, t_sec, t_ms, j
cdef int N = len(date_vec)
我在这里选择对象类型。我想这可能是瓶颈。
cdef np.ndarray[object] out_ar2 = np.empty(N, dtype=object)
cdef tm *out_ar = <tm *> malloc(N * sizeof(tm))
cdef char *date_str = <char *> malloc(N * 8 * sizeof(char) )
cdef tm result;
with nogil, parallel():
for i in prange(N):
sprintf(&date_str[i*8], "%d", date_vec[i])
strptime(&date_str[i*8],"%Y%m%d",&out_ar[i])
out_ar2是整个代码中耗时的部分。
for j in range(N):
out_ar2[j] = date(out_ar[j].tm_year + 1900, out_ar[j].tm_mon + 1, out_ar[j].tm_mday)
free(out_ar)
free(date_str)
return(out_ar2)