13

非常に大きな netCDF ファイル (それぞれ ~400 Gb) のデータを処理しようとしています。各ファイルにはいくつかの変数があり、すべてシステム メモリよりもはるかに大きくなります (例: 180 Gb と 32 Gb RAM)。私はnumpyを使用しようとしています.netCDF4-pythonは、一度にスライスをコピーしてそのスライスを操作することにより、これらの変数に対していくつかの操作を行います。残念ながら、各スライスを読み取るだけで非常に長い時間がかかり、パフォーマンスが低下しています。

たとえば、変数の 1 つは shape の配列です(500, 500, 450, 300)。スライスを操作したい[:,:,0]ので、次のようにします。

import netCDF4 as nc

f = nc.Dataset('myfile.ncdf','r+')
myvar = f.variables['myvar']
myslice = myvar[:,:,0]

しかし、最後のステップには非常に長い時間がかかります (私のシステムでは約 5 分)。たとえば、形状の変数を(500, 500, 300)netcdf ファイルに保存した場合、同じサイズの読み取り操作には数秒しかかかりません。

これをスピードアップする方法はありますか?明らかな方法は、選択しているインデックスが最初に表示されるように配列を転置することです。しかし、このような大きなファイルでは、これをメモリ内で実行することは不可能であり、単純な操作にすでに長い時間がかかることを考えると、それを試みるのはさらに遅くなるようです。私が望むのは、Fortran のインターフェイス get_vara 関数のように、netcdf ファイルのスライスをすばやく読み取る方法です。または、配列を効率的に転置する何らかの方法。

4

2 に答える 2

8

ここに文書化されている nccopy ユーティリティを使用して、大きすぎてメモリに収まらない netCDF 変数を転置できます。

http://www.unidata.ucar.edu/netcdf/docs/guide_nccopy.html

アイデアは、変数に必要なチャンク (多次元タイル) の形状を指定して、ファイルを「再チャンク」することです。バッファとして使用するメモリの量とチャンク キャッシュに使用するメモリの量を指定できますが、これらの使用の間でメモリを最適に使用する方法が明確ではないため、いくつかの例を試して時間を計る必要がある場合があります。変数を完全に転置するのではなく、スライスの 2 つの大きな次元に沿って多くのデータを持ち、他の次元に沿ってわずかな値しか持たないチャンクを指定することで、変数を「部分的に転置」したいと思うでしょう。

于 2012-08-22T22:42:33.107 に答える
3

これはコメントであり、回答ではありませんが、上記についてコメントすることはできません。申し訳ありません。

myvar[:,:,i]で、を処理しiたいことを理解していますrange(450)。その場合、次のようなことを行います。

for i in range(450):
    myslice = myvar[:,:,i]
    do_something(slice)

ボトルネックはにアクセスすることmyslice = myvar[:,:,i]です。アクセスにかかる時間を比較してみましたmoreslices = myvar[:,:,0:n]か?それは連続データであり、おそらくそれで時間を節約することができます。メモリが許す限りの大きさを選択nし、次のデータチャンクを処理moreslices = myvar[:,:,n:2n]します。

于 2012-08-22T13:36:53.663 に答える