4

pandas の DataFrame インデックスとして使用するために、約 10 ~ 20M の ISO 日時文字列をマイクロ秒の精度で datetime64 にすばやくキャストしたいと考えています。

私は pandas 0.9 を使用しており、gitで提案された解決策を試しましたが、20 ~ 30 分かかるか、完了しないことがわかりました。

私は問題を見つけたと思います。これら 2 つの速度を比較します。

rng = date_range('1/1/2000', periods=2000000, freq='ms')
strings = [x.strftime('%Y-%m-%d %H:%M:%S.%f') for x in rng]
timeit to_datetime(strings)

私のラップトップでは、〜300ミリ秒です。

rng = date_range('1/1/2000', periods=2000000, freq='ms')
strings = [x.strftime('%Y%m%dT%H%M%S.%f') for x in rng]
timeit to_datetime(strings)

私のラップトップで、永遠にそして一日。

数千万のスタンプのフォーマットをループして修正するのはおそらくかなり遅いので、タイムスタンプを生成するc++コードを変更して、今のところより詳細なISO形式にします...

4

1 に答える 1

4

高速なパーサー コードは、ダッシュとコロンを含む標準の ISO-8601 のみを処理します。文字列が適切な形式である場合は、ご覧のとおり非常に高速です。コードは GitHub にあり、より多くのケースを処理できるように (できれば標準形式の速度をあまり落とさずに) 確実に改善できます。

部分的に満足できる回避策としてdatetime.strptime、文字列を に変換し、datetime.datetimeその結果を に渡すことができto_datetimeます。

In [4]: paste
rng = date_range('1/1/2000', periods=2000000, freq='ms')
strings = [x.strftime('%Y%m%dT%H%M%S.%f') for x in rng]

## -- End pasted text --

In [5]: iso_strings = [x.strftime('%Y-%m-%d %H:%M:%S.%f') for x in rng]

In [6]: %timeit result = to_datetime(iso_strings)
1 loops, best of 3: 479 ms per loop

In [7]: f = lambda x: datetime.strptime(x, '%Y%m%dT%H%M%S.%f')

In [8]: f(strings[0])
Out[8]: datetime.datetime(2000, 1, 1, 0, 0)

In [9]: %time result = to_datetime(map(f, strings))
CPU times: user 48.47 s, sys: 0.01 s, total: 48.48 s
Wall time: 48.54 s

100 倍違いますが、1000% 以上遅いよりははるかに優れています。Cバージョンのstrptimeto_datetimeを使用すると、はるかに高速になるはずです。練習は読者に任されていると思います

いつかの todo: http://github.com/pydata/pandas/issues/2213

于 2012-11-09T21:12:37.097 に答える