8

4D データ配列 (時間、深さ、緯度、経度。以下dask_arrayに示す) の形状は通常 (6000, 31, 189, 192) で、サイズは ~25GB (したがって、dask を使用したいのですが、numpy を使用してこれらの配列を処理しようとすると、メモリ エラーが発生します)。

各レベル/緯度/経度のポイントで時間軸に沿って 3 次多項式を当てはめ、結果の 4 つの係数を保存する必要があります。したがってchunksize=(6000, 1, 1, 1)、グリッド ポイントごとに個別のチャンクがあるように設定しました。

これは、3 次多項式の係数を取得するための私の関数です (time_axis軸の値は、他の場所で定義されたグローバルな 1D numpy 配列です)。

def my_polyfit(data):    
    return numpy.polyfit(data.squeeze(), time_axis, 3)

(したがって、この場合、numpy.polyfit長さ 4 のリストを返します)

これは、各チャンクに適用する必要があると思ったコマンドです。

dask_array.map_blocks(my_polyfit, chunks=(4, 1, 1, 1), drop_axis=0, new_axis=0).compute()

これにより、時間軸がなくなり (したがってdrop_axis=0)、その場所に (長さ 4 の) 新しい係数軸があります。

このコマンドを実行すると が表示されるので、どこでどのように?IndexError: tuple index out of rangeの使用を誤解したのか疑問に思っています。map_blocks

4

2 に答える 2

8

関数が消費するのと同じ次元の配列を返すと、エクスペリエンスがよりスムーズになると思います。たとえば、次のように関数を定義することを検討できます。

def my_polyfit(data):
    return np.polyfit(data.squeeze(), ...)[:, None, None, None]

new_axisその後、おそらくdrop_axisビットを無視できます。

パフォーマンスに関しては、より大きなチャンクサイズの使用を検討することもできます。チャンクあたり 6000 個の数値で、100 万を超えるチャンクがあるため、実際の計算よりもスケジューリングに多くの時間を費やすことになるでしょう。通常、サイズが数メガバイトのチャンクを撮影します。もちろん、チャンクサイズを大きくすると、マップされた関数がより複雑になります。

In [1]: import dask.array as da

In [2]: import numpy as np

In [3]: def f(b):
    return np.polyfit(b.squeeze(), np.arange(5), 3)[:, None, None, None]
   ...: 

In [4]: x = da.random.random((5, 3, 3, 3), chunks=(5, 1, 1, 1))

In [5]: x.map_blocks(f, chunks=(4, 1, 1, 1)).compute()
Out[5]: 
array([[[[ -1.29058580e+02,   2.21410738e+02,   1.00721521e+01],
         [ -2.22469851e+02,  -9.14889627e+01,  -2.86405832e+02],
         [  1.40415805e+02,   3.58726232e+02,   6.47166710e+02]],
         ...
于 2016-03-29T04:09:22.797 に答える