2017-08-08 10 views
0

私は文字列のリスト(ユニコード)を持っています。同様に:文字列のリストに対して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

ループを使用せずにリスト内のアイテムをどのように実行しますか?鮮明な 'map'でも、シーンの背後に* loop *する必要があります。 –

+0

リストはどのくらいですか?それをPandasシリーズに変換するのは価値があります。 – 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.45秒で800Kです(私のタイミングはシングルループですが)...おそらく。 – roganjosh

2

ループなしでアイテムを反復処理することはできません。あなたはこの使用できる1行のソリューションの場合 :あなたは本当に(あなたのコード内で)ループを省略したい場合は

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

まだバックグラウンドでループを使用していますが、最適化されています。

よろしく、公園

関連する問題