2017-08-08 63 views
0

我有一個字符串列表(unicode)。像這樣:在字符串列表中使用strptime()。不能使用循環

>>> 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'] 

我想將這個字符串列表轉換爲一個datetime對象列表。像這樣:

>>> 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') 

任何人都可以指出我在正確的方向嗎?

提前致謝!

+5

如何運行列表中的項目而不使用循環?即使是脆弱的「地圖」,也不得不在幕後操作。 –

+0

列表多久?可能有一點將其轉換爲熊貓系列是值得的。 – roganjosh

+1

你對列表解讀感覺如何? – Stael

回答

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 
+0

這是我迄今爲止最快的選擇。謝謝。 – Tanmay

+1

沒問題。你可能會考慮把它放在你的流程的更上游的一個數組中,以此來加快速度。但是,我不知道您是否可以在其他地方負擔這些開銷,或者您是否仍然可靠地進行第二次處理。這是在1.45s 800K(雖然我的時間是一個單一的循環),所以......也許。 – roganjosh

2

您不能在沒有循環的情況下迭代項目。 對於一條線解決方案,您可以使用此:

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

如果你真的想省略環路(在你的代碼),你可以使用map()

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

要知道,雖然,即使map()最終將使用循環來做到這一點。沒有迭代列表中的每個項目就沒有辦法做到這一點。然而,聰明的代碼會在後臺總是有一個循環。

如果你真的需要它是超快的,那麼使用python的唯一方法是使用C extensions

+0

感謝您的C擴展提示。我會仔細看看的。 – Tanmay

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)] 

它仍然在後臺使用循環,但它是相當優化。

問候,公園

相關問題