从日期时间列表中提取持续时间列表的更好方法

时间:2014-06-24 18:44:42

标签: python list numpy

我有一个日期时间列表。我想将其转换为一个列表,其中持续时间显示在日期时间之间。下面的代码工作正常,但如果我看一下它似乎有点矫枉过正。首先,我将列表转换为numpy数组,然后创建dureation数组并将其转换回秒列表。我多次遇到过这种情况,因此如果有人告诉我这样做最有效的方法会很棒。

import datetime;
from numpy import *

times = [datetime.datetime(2014, 6, 23, 18, 56, 30),
 datetime.datetime(2014, 6, 23, 18, 57),
 datetime.datetime(2014, 6, 23, 18, 57, 30),
 datetime.datetime(2014, 6, 23, 18, 58),
 datetime.datetime(2014, 6, 23, 18, 58, 30),
 datetime.datetime(2014, 6, 23, 18, 59),
 datetime.datetime(2014, 6, 23, 18, 59, 30)]

seconds = array(times)
start = times[0]
duration = seconds - start

secs = [];
for item in duration:
    secs.append(item.seconds);

# result: secs = [0, 30, 60, 90, 120, 150, 180]

4 个答案:

答案 0 :(得分:4)

您可以直接对datetime个对象进行减法:

>>> [(a - times[0]).total_seconds() for a in times]
[0, 30, 60, 90, 120, 150, 180]

当你减去两个datetime.datetime个对象时,会得到一个datetime.timedelta个对象,它表示两个datetimes之间的时间量。因此,您可以遍历列表,从第一次开始减去当前时间,并使用它返回的total_seconds()对象中的timedelta方法来获得以秒为单位的差异。

答案 1 :(得分:1)

numpy.diff应该有效: http://docs.scipy.org/doc/numpy/reference/generated/numpy.diff.html

一旦你的日期时间列表变大,它应该会更快(不确定为什么你在上面使用numpy)。如果切换到numpy datetime types,则可能会获得更高的性能。

>>> times = numpy.array(times)
>>> diffs =numpy.diff(times)
>>> diffs
array([datetime.timedelta(0, 30), datetime.timedelta(0, 30),
       datetime.timedelta(0, 30), datetime.timedelta(0, 30),
       datetime.timedelta(0, 30), datetime.timedelta(0, 30)], dtype=object)

如果您想要原始秒数,可以通过timedelta.total_seconds()方法获取原始数据:

seconds = [x.total_seconds() for x in diffs]

编辑:

如果所有的增量都应该与第一个日期时间值相关,那么你可以这样做:

seconds = [x.total_seconds() for x in times - times[0]]

不需要diff然后......

答案 2 :(得分:1)

这样的东西会起作用(不需要numpy):

times = [datetime.datetime(2014, 6, 23, 18, 56, 30),
    datetime.datetime(2014, 6, 23, 18, 57),
    datetime.datetime(2014, 6, 23, 18, 57, 30),
    datetime.datetime(2014, 6, 23, 18, 58),
    datetime.datetime(2014, 6, 23, 18, 58, 30),
    datetime.datetime(2014, 6, 23, 18, 59),
    datetime.datetime(2014, 6, 23, 18, 59, 30)]

start = times[0]
output = [ (t - start).seconds for t in times]

print output
# [0, 30, 60, 90, 120, 150, 180]

编辑:我看到我被打败了!干得好:D

答案 3 :(得分:1)

使用行duration = seconds - start,您可以在numpy中创建时间增量列表:

>>> duration
[datetime.timedelta(0) datetime.timedelta(0, 30) datetime.timedelta(0, 60) datetime.timedelta(0, 90) datetime.timedelta(0, 120) datetime.timedelta(0, 150) datetime.timedelta(0, 180)]

因此,您可以使用numpy.vectorize直接生成所需内容,以生成一个新数组,该数组将duration数组中的总秒数分开。

如果您只是这样做一次,您可以使用vectorize作为类似地图的丢弃函数:

>>> vectorize(lambda td: td.total_seconds())(duration)
[   0.   30.   60.   90.  120.  150.  180.]

或者让它多次使用:

>>> v=vectorize(lambda td: td.total_seconds())
>>> v(duration), v(duration*2)
[   0.   30.   60.   90.  120.  150.  180.] [   0.   60.  120.  180.  240.  300.  360.]

优势在于,如果你在numpy中工作,这会使数据保持不变 - 不会像列表理解那样创建Python的往返。