15

ISO 形式の日付を表す文字列のリストを含むデータ ファイルがあります。現在、私はそれらを使用して読んでいます:

mydates = [ datetime.datetime.strptime(timdata[x], "%Y-%m-%dT%H:%M:%S") for x in range(len(timedata)) ]

これは非常に簡単に見えますが、〜25000の日付の巨大なリストを操作すると、途方もなく遅くなります->変換されたリストごとに約0.34秒。私はそのようなリストを何千も持っているので、より速い方法を探しています。しかし、私はまだそれを見つけることができませんでした。dateutil パーサーのパフォーマンスはさらに低下します...

4

2 に答える 2

22

約3倍高速化する方法を次に示します。

元のバージョン:

In [23]: %timeit datetime.datetime.strptime("2013-01-01T01:23:45", "%Y-%m-%dT%H:%M:%S")
10000 loops, best of 3: 21.8 us per loop

より高速なバージョン:

In [24]: p = re.compile('[-T:]')

In [26]: %timeit datetime.datetime(*map(int, p.split("2013-01-01T01:23:45")))
100000 loops, best of 3: 7.28 us per loop

これは明らかに、 ほど柔軟ではありませんstrptime()

編集:単一の正規表現を使用して日付コンポーネントを抽出すると、わずかに高速になります:

In [48]: pp = re.compile(r'(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})')

In [49]: %timeit datetime.datetime(*map(int, pp.match("2013-01-01T01:23:45").groups()))
100000 loops, best of 3: 6.92 us per loop
于 2013-01-04T19:23:01.533 に答える
12

インデックス作成/スライスは、@NPE で使用される正規表現よりも高速のようです。

In [47]: def with_indexing(dstr):                              
   ....:     return datetime.datetime(*map(int, [dstr[:4], dstr[5:7], dstr[8:10],
   ....:                               dstr[11:13], dstr[14:16], dstr[17:]])) 

In [48]: p = re.compile('[-T:]')

In [49]: def with_regex(dt_str):
   ....:     return datetime.datetime(*map(int, p.split(dt_str)))

In [50]: %timeit with_regex(dstr)
100000 loops, best of 3: 3.84 us per loop

In [51]: %timeit with_indexing(dstr)
100000 loops, best of 3: 2.98 us per loop

のようなファイル パーサーを使用するとnumpy.genfromtxtconverters引数と高速な文字列解析メソッドを使用すると、ファイル全体を 0.5 秒未満で読み取って解析できると思います。

次の関数を使用して、約 25000 行、インデックスとして ISO 日付文字列、10 データ列を含むサンプル ファイルを作成しました。

import numpy as np
import pandas as pd

def create_data():
    # create dates
    dates = pd.date_range('2010-01-01T00:30', '2013-01-04T23:30', freq='H')
    # convert to iso
    iso_dates = dates.map(lambda x: x.strftime('%Y-%m-%dT%H:%M:%S'))
    # create data
    data = pd.DataFrame(np.random.random((iso_dates.size, 10)) * 100,
                        index=iso_dates)
    # write to file
    data.to_csv('dates.csv', header=False)

次のコードを使用してファイルを解析するよりも:

In [54]: %timeit a = np.genfromtxt('dates.csv', delimiter=',',
                                   converters={0:with_regex})
1 loops, best of 3: 430 ms per loop

In [55]: %timeit a = np.genfromtxt('dates.csv', delimiter=',',
                                   converters={0:with_indexing})
1 loops, best of 3: 391 ms per loop

pandas (numpy に基づく) には、さらに高速な C ベースのファイル パーサーがあります。

In [56]: %timeit df = pd.read_csv('dates.csv', header=None, index_col=0, 
                                  parse_dates=True, date_parser=with_indexing)
10 loops, best of 3: 167 ms per loop
于 2013-01-04T23:48:16.677 に答える