私はいくつかの大きなファイル(約10GBのgzipファイル)を持っています。これらのファイルには、ASCIIヘッダが入っていて、原則numpy.recarraysがそれぞれ約3MBあり、それらを「イベント」と呼びます。私の最初のアプローチは、このように見えた:zipファイルの効率的なnumpy.fromfile?
f = gzip.GzipFile(filename)
f.read(10000) # fixed length ascii header
event_dtype = np.dtype([
('Id', '>u4'), # simplified
('UnixTimeUTC', '>u4', 2),
('Data', '>i2', (1600,1024))
])
event = np.fromfile(f, dtype = event_dtype, count=1)
それは本当に低レベルの呼び出し(かなり古いチケットhttps://github.com/numpy/numpy/issues/1103を見つけた)を行うためnp.fromfileは、実際のファイルオブジェクトを必要とするので、これは、不可能です。
私は理解してだから私はこのようにそれをしなければならない。
s = f.read(event_dtype.itemsize)
event = np.fromstring(s, dtype=event_dtype, count=1)
そして、はい、それは働きます!しかし、これはひどく非効率的ではありませんか? memが割り当てられておらず、すべてのイベントでガベージが収集されていますか? 私のラップトップでは、16イベント/秒~50MB/sのようなものになります
誰かがスマートな方法を知っていれば、一度memを割り振り、numpyをそのmemに直接読み込ませるのは難しいです。
Btw。私は物理学者なので、まだこのビジネスの初心者です。
I/Oがかかる時間は、その文字列の割り当て/割り当て解除に要した時間よりも数千倍大きいです。ボトルネックがどこにあるのかを確認し、最適化するためにコードをプロファイルする必要があります。ボトルネックがどこにあるかを推測することは、効率的にプログラミングすることに慣れていない場合でも、さらに悪いことです。 – Bakuriu
読み込み専用の配列であれば、numpy.frombufferを使ってメモリの重複を避け、その文字列をメモリバッファとして使うことができます。 –
@Bakariuはそれを明確に表現してくれてありがとう。コードをプロファイリングする経験はありません。そして、その良いことは、その推測は悪いです。 @ジョーキングトン。 –