2017-05-08 13 views
4

何千ものGRIBファイルがあるディレクトリがあるとします。これらのファイルをdask配列にロードして、それらを照会できるようにします。これをやり遂げるにはどうすればいいですか?以下の試みはうまくいくようですが、各GRIBファイルを開く必要があり、実行には時間がかかり、すべてのメモリが必要になります。より良い方法が必要です。GRIBファイルのディレクトリをDask配列にロードする方法

私の試み:

import dask.array as da 
from dask import delayed 
import gdal 
import glob 
import os 


def load(filedir): 
    files = sorted(glob.glob(os.path.join(filedir, '*.grb'))) 
    data = [da.from_array(gdal.Open(f).ReadAsArray(), chunks=[500,500,500], name=f) for f in files] 
    return da.stack(data, axis=0) 

file_dir = ... 
array = load(file_dir) 
+0

daskで構築され、PyNIO経由でGRIBをサポートしているxarrayを試しましたか?しかし、データをすばやく分析したい場合は、hdf5またはNetCDF4に書き直して、適切なチャンクを使用して解析することは非常に簡単になります。 – kakk11

答えて

4

これを行うための最善の方法は、dask.delayedを使用することです。この場合、配列を読み取る遅延関数を作成し、da.from_delayed関数を使用してオブジェクトdelayedからdask配列を作成します。

これは、各ファイルを読み込むための1つのタスクを作成することに注意してください。個々のファイルが大きい場合は、load機能でチャンクすることができます。私はgdalに慣れていませんが、ReadAsArrayメソッドの簡単な見方から、これはxoff/yoff/xsize/ysizeのパラメータ(わからない)で実行可能です。あなたはこのコードを自分で書く必要がありますが、大きなファイルの方がパフォーマンスが良いかもしれません。

また、上記のコードを使用して、rechunkを呼び出して小さなチャンクに再チャンクすることもできます。これにより、1つのタスクで各ファイルを読み込むことになりますが、それ以降の手順は小さなチャンクでも機能します。これが価値があるかどうかは、個々のファイルのサイズによって決まります。

x = x.rechunk((500, 500, 500)) # or whatever chunks you want 
+0

コードは60個のファイルに対して実行したときに機能します。 17,500以上のファイルを実行しようとすると、メモリエラーが発生します。各ファイルには寸法(52,224,464)があります。それらを積み重ねた後、チャンクサイズ(1、1、224、464)になった。私がxにするのは 'x [:,:、80、80] .compute()'です。もう1つの重要な詳細は、ディスクに流出するためにキャッシュを提供しても、メモリエラーを防ぐことはできませんでした。 –

+0

この場合、再チャンクは実際には意味がありません。後でサブセットをサブセレクションするだけです。一般的には、個々のタスクのコストがスケジューラーのオーバーヘッドよりもはるかに大きいチャンクを十分に大きくしたいとします。詳細はhttp://dask.pydata.org/en/latest/array-creation.html#chunksをご覧ください。まともな経験則は、各チャンクに少なくとも1e6の要素があり、通常はそれ以上です。私はまったくリチャッチせず、ファイルごとにチャンクを持っています。 –

+0

再チャンクを行うときは、ファイルのブロックサイズ(チャンクサイズ)も調べてください。ネイティブブロックサイズ(または複数)を尊重することで、パフォーマンスが大幅に向上します。ディスクから同じデータを何度も何度も読み取ることはできません。 GDALのブロックキャッシュは、それを防ぐのにも役立ちます。 –