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

时间:2013-09-26 21:31:13

标签: python arrays loops datetime numpy

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

>>>dt[0]
datetime.timedelta(0, 1, 36000)

如何将dt转换为仅包含秒而不循环的数组dt_sec?我当前的解决方案(有效,但我不喜欢)是:

dt_sec = zeros((len(dt),1))
for i in range(0,len(dt),1):
    dt_sec[i] = dt[i].total_seconds()

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

由于

5 个答案:

答案 0 :(得分:12)

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

设置例如:

import datetime
import numpy

times = numpy.array([datetime.timedelta(0, 1, 36000)])

代码:

times.astype("timedelta64[ms]").astype(int) / 1000
#>>> array([ 1.036])

由于人们似乎没有意识到这是最佳解决方案,因此以下是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]"

结果:

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

初始翻译所需的时间大约是矢量化表达式的两倍,但是从那时起的每个操作到timedelta数组的永久性将大约快20倍。


如果您再也不打算再使用timedelta,请考虑问自己为什么要在第一时间进行增量(而不是timedelta64 s),然后使用{ {1}}表达。它不那么原生,但出于某种原因它更快。

答案 1 :(得分:9)

import numpy as np

helper = np.vectorize(lambda x: x.total_seconds())
dt_sec = helper(dt)

答案 2 :(得分:0)

我喜欢prgao建议使用np.vectorize。如果您只想要一个Python列表,您还可以执行以下操作:

dt_sec = map(datetime.timedelta.total_seconds, dt)

答案 3 :(得分:0)

一种方便而优雅的方法是使用pandas.Series并使用dt.total_seconds属性:

import numpy as np
import pandas as pd

# create example datetime arrays
arr1 = np.array(['2007-07-13', '2006-01-13', '2010-08-13'], dtype='datetime64')
arr2 = np.array(['2007-07-15', '2006-01-18', '2010-08-22'], dtype='datetime64')

# timedelta array
td = arr2 - arr1

# get total seconds
pd.Series(td).dt.total_seconds()
0    172800.0
1    432000.0
2    777600.0
dtype: float64

答案 4 :(得分:-2)

您可以使用“列表理解”:

dt_sec = [delta.total_seconds() for delta in dt]

在幕后,numpy应该把它翻译成一个非常快速的操作。