Я пытаюсь ускорить преобразование строки в дату. Я предпочел Cython. После того, как я получил c tm struct. Я конвертирую tm struct в python datetime с помощью функции cpython.datetime.date. Оно работает. Примерно на 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)