在字符串列表上使用strptime()。不能使用循环

时间:2017-08-08 11:46:44

标签: python datetime typeerror strptime

我有一个字符串列表(unicode)。像这样:

>>> tstamp
[u'2017-08-08T08:51:20.465Z', u'2017-08-08T08:51:27.871Z', u'2017-08-08T08:51:33.399Z', u'2017-08-08T08:51:37.530Z', u'2017-08-08T08:51:47.248Z', u'2017-08-08T08:51:50.414Z', u'2017-08-08T08:51:54.707Z', u'2017-08-08T08:51:54.781Z']

我想将此字符串列表转换为日期时间对象列表。像这样:

>>> dtstamp
[datetime.datetime(2017, 8, 8, 8, 51, 20, 465000), datetime.datetime(2017, 8, 8, 8, 51, 27, 871000), datetime.datetime(2017, 8, 8, 8, 51, 33, 399000), datetime.datetime(2017, 8, 8, 8, 51, 37, 530000), datetime.datetime(2017, 8, 8, 8, 51, 47, 248000), datetime.datetime(2017, 8, 8, 8, 51, 50, 414000), datetime.datetime(2017, 8, 8, 8, 51, 54, 707000), datetime.datetime(2017, 8, 8, 8, 51, 54, 781000)]

我的解决方案非常粗糙,我希望在不使用任何循环的情况下进行此转换。转换速度至关重要。到目前为止,这是我的代码:

dtstamp = [0]*len(tstamp)
for i in range(0,len(tstamp)):
     dtstamp[i] = datetime.datetime.strptime(tstamp[i], '%Y-%m-%dT%H:%M:%S.%fZ')

它做我想做的事,但会很慢。我想过尝试这个,但是不起作用:

dtstamp = datetime.datetime.strptime(tstamp, '%Y-%m-%dT%H:%M:%S.%fZ')

任何人都能指出我正确的方向吗?

提前致谢!

4 个答案:

答案 0 :(得分:5)

只需在列表中使用pd.to_datetime即可获得显着的加速。但是,即使您可以调整方法,我也不会认为您每秒可以获得600,000次转换。

import pandas as pd
import datetime as dt

my_list = [u'2017-08-08T08:51:20.465Z', u'2017-08-08T08:51:27.871Z', u'2017-08-08T08:51:33.399Z', u'2017-08-08T08:51:37.530Z', u'2017-08-08T08:51:47.248Z', u'2017-08-08T08:51:50.414Z', u'2017-08-08T08:51:54.707Z', u'2017-08-08T08:51:54.781Z']
new_list = []
for x in xrange(100000):
    new_list.extend(my_list)

def basic_list_approach(the_list):
    return [dt.datetime.strptime(item, '%Y-%m-%dT%H:%M:%S.%fZ') for item in the_list]

def pandas_approach(the_list):
    converted = pd.to_datetime(the_list)
    return converted

%timeit basic_list_approach(new_list)
1 loop, best of 3: 12.6 s per loop

%timeit pandas_approach(new_list)
1 loop, best of 3: 1.45 s per loop

答案 1 :(得分:2)

您无法循环遍历项目。 对于单行解决方案,您可以使用:

import dateutil.parser
print [dateutil.parser.parse(i) for i in tstamp]

答案 2 :(得分:1)

如果你真的想省略循环(在你的代码中),你可以使用map()

map(lambda item: datetime.datetime.strptime(item, '%Y-%m-%dT%H:%M:%S.%fZ'), 
    tstamp)

请注意,即使map()最终也会使用循环来执行此操作。如果不迭代列表中的每个项目,都无法做到这一点。无论代码多么聪明,幕后某处总会有一个循环。

如果你真的需要它超快,那么用python做这件事的唯一方法是使用C extensions

答案 3 :(得分:1)

你有没有尝试过列表理解?

[datetime.datetime.strptime(x, '%Y-%m-%dT%H:%M:%S.%fZ')for x in tstamp]
# [datetime.datetime(2017, 8, 8, 8, 51, 20, 465000), datetime.datetime(2017, 8, 8, 8, 51, 27, 871000), datetime.datetime(2017, 8, 8, 8, 51, 33, 399000), datetime.datetime(2017, 8, 8, 8, 51, 37, 530000), datetime.datetime(2017, 8, 8, 8, 51, 47, 248000), datetime.datetime(2017, 8, 8, 8, 51, 50, 414000), datetime.datetime(2017, 8, 8, 8, 51, 54, 707000), datetime.datetime(2017, 8, 8, 8, 51, 54, 781000)]

它仍然在后台使用循环,但它相当优化。

问候,Koen