在python 2.7中将包含datetime.timedelta的numpy数组转换为秒的优雅方式
我有一个名为在python 2.7中将包含datetime.timedelta的numpy数组转换为秒的优雅方式,python,arrays,loops,datetime,numpy,Python,Arrays,Loops,Datetime,Numpy,我有一个名为dt的numpy数组。每个元素的类型为datetime.timedelta。例如: >>>dt[0] datetime.timedelta(0, 1, 36000) import datetime import numpy times = numpy.array([datetime.timedelta(0, 1, 36000)]) 如何将dt转换为数组dt_sec,该数组只包含秒而不循环?我目前的解决方案(可行,但我不喜欢)是: 我试图使用dt.total_s
dt
的numpy数组。每个元素的类型为datetime.timedelta
。例如:
>>>dt[0]
datetime.timedelta(0, 1, 36000)
import datetime
import numpy
times = numpy.array([datetime.timedelta(0, 1, 36000)])
如何将dt
转换为数组dt_sec
,该数组只包含秒而不循环?我目前的解决方案(可行,但我不喜欢)是:
我试图使用dt.total_seconds()
,但它当然不起作用。你知道如何避免这种循环吗
谢谢您可以使用“列表理解”:
在幕后,numpy应该将其转化为一种非常快速的操作。
numpy
有自己的datetime
和timedelta
格式。只要使用它们;)
设置例如:
>>>dt[0]
datetime.timedelta(0, 1, 36000)
import datetime
import numpy
times = numpy.array([datetime.timedelta(0, 1, 36000)])
代码:
由于人们似乎没有意识到这是最好的解决方案,以下是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倍左右
如果你再也不打算使用那些<代码> TimeDela/Case>s,请考虑一下自己为什么要制作Deltas(与
np.vectorize
,如所建议的。如果只需要Python列表,还可以执行以下操作:
dt_sec = map(datetime.timedelta.total_seconds, dt)
一种方便而优雅的方法是使用
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()
为什么不在
lambda
中使用x.seconds
?另外,如果数组是平面的一维数组,那么map(lambda x:x.total_seconds(),dt)
会更快吗?当然是真的(最后必须将列表转换为数组)。我不知道矢量化…这是一个多么有用的函数!谢谢numpy
在幕后没有做任何事情。见鬼,它可能比正常的列表上的循环要慢。与此答案相关的一些链接:Series.dt
:Series.dt.total_seconds
:
dt_sec = map(datetime.timedelta.total_seconds, dt)
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