Сначала предположим, что у вас есть строки в формате ISO, '% Y-% m-% dT% H:% M:% S.% f', в list
(давайте также не будем рассматривать декодирование из байтового массива для сейчас):
from datetime import datetime, timedelta
base, n = datetime(2000, 1, 1, 1, 2, 3, 420001), 1000
datelist = [(base + timedelta(days=i)).isoformat(' ') for i in range(n)]
# datelist
# ['2000-01-01 01:02:03.420001'
# ...
# '2002-09-26 01:02:03.420001']
из строки в объект datetime
Давайте определим некоторые функции, которые анализируют строку до datetime
, используя разные методы:
import re
import numpy as np
def strp_isostr(l):
return list(map(datetime.fromisoformat, l))
def isostr_to_nparr(l):
return np.array(l, dtype=np.datetime64)
def split_isostr(l):
def splitter(s):
tmp = s.split(' ')
tmp = tmp[0].split('-') + [tmp[1]]
tmp = tmp[:3] + tmp[3].split(':')
tmp = tmp[:5] + tmp[5].split('.')
return datetime(*map(int, tmp))
return list(map(splitter, l))
def resplit_isostr(l):
# return list(map(lambda s: datetime(*map(int, re.split('T|-|\:|\.', s))), l))
return [datetime(*map(int, re.split('\ |-|\:|\.', s))) for s in l]
def full_stptime(l):
# return list(map(lambda s: datetime.strptime(s, '%Y-%m-%dT%H:%M:%S.%f'), l))
return [datetime.strptime(s, '%Y-%m-%d %H:%M:%S.%f') for s in l]
Если я запускаю %timeit
в консоли I Python для этих функций на моем компьютере, я получаю
%timeit strp_isostr(datelist)
98.2 µs ± 766 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit isostr_to_nparr(datelist)
1.49 ms ± 13.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit split_isostr(datelist)
3.02 ms ± 236 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit resplit_isostr(datelist)
3.8 ms ± 256 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit full_stptime(datelist)
16.7 ms ± 780 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Итак, мы можем сделать вывод, что встроенный datetime.fromisoformat
- безусловно, самый быстрый вариант для ввода 1000 элементов. Однако это предполагает, что вы хотите работать с list
. Если вам все равно нужно np.array
из datetime64
, переход прямо к нему кажется лучшим вариантом.
сторонний вариант: ciso8601
Если вы можете установить дополнительные пакеты, ciso8601
заслуживает внимания:
import ciso8601
def ciso(l):
return list(map(ciso8601.parse_datetime, l))
%timeit ciso(datelist)
138 µs ± 1.83 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
от объекта datetime до секунд с начала эпохи
Просмотр преобразования объекта datetime
в метку времени POSIX , использование наиболее очевидного метода datetime.timestamp
кажется наиболее эффективным:
import time
def dt_ts(l):
return list(map(datetime.timestamp, l))
def timetup(l):
return list(map(time.mktime, map(datetime.timetuple, l)))
%timeit dt_ts(strp_isostr(datelist))
572 µs ± 4.57 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit timetup(strp_isostr(datelist))
1.44 ms ± 15.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)