在python 2.7中将包含datetime.timedelta的numpy数组转换为秒的优雅方法

otm*_*ger 9 python arrays datetime loops numpy

我有一个叫做numpy的数组dt.每个元素都是类型datetime.timedelta.例如:

>>>dt[0]
datetime.timedelta(0, 1, 36000)
Run Code Online (Sandbox Code Playgroud)

如何转换dtdt_sec只包含秒而不循环的数组?我目前的解决方案(有效,但我不喜欢)是:

dt_sec = zeros((len(dt),1))
for i in range(0,len(dt),1):
    dt_sec[i] = dt[i].total_seconds()
Run Code Online (Sandbox Code Playgroud)

我尝试使用,dt.total_seconds()但当然它没有用.关于如何避免这种循环的任何想法?

谢谢

Vee*_*rac 12

numpy有自己datetimetimedelta格式.只需使用它们;).

设置例如:

import datetime
import numpy

times = numpy.array([datetime.timedelta(0, 1, 36000)])
Run Code Online (Sandbox Code Playgroud)

码:

times.astype("timedelta64[ms]").astype(int) / 1000
#>>> array([ 1.036])
Run Code Online (Sandbox Code Playgroud)

由于人们似乎没有意识到这是最好的解决方案,所以这里是timedelta64数组与datetime.datetime数组的一些时序:

SETUP="
import datetime
import numpy

times = numpy.array([datetime.timedelta(0, 1, 36000)] * 100000)
numpy_times = times.astype('timedelta64[ms]')
"

python -m timeit -s "$SETUP" "numpy_times.astype(int) / 1000"
python -m timeit -s "$SETUP" "numpy.vectorize(lambda x: x.total_seconds())(times)"
python -m timeit -s "$SETUP" "[delta.total_seconds() for delta in times]"
Run Code Online (Sandbox Code Playgroud)

结果:

100 loops, best of 3: 4.54 msec per loop
10 loops, best of 3: 99.5 msec per loop
10 loops, best of 3: 67.1 msec per loop
Run Code Online (Sandbox Code Playgroud)

初始转换将花费大约两倍于向量化表达式的时间,但是从那时开始的每个操作到该timedelta阵列上的永久性将大约快20倍.


如果你再也不打算再使用它们timedelta,可以考虑问自己为什么要timedelta64在第一时间做出增量(而不是s),然后使用numpy.vectorize表达式.它不那么原生,但出于某种原因它更快.


prg*_*gao 10

import numpy as np

helper = np.vectorize(lambda x: x.total_seconds())
dt_sec = helper(dt)
Run Code Online (Sandbox Code Playgroud)