2017-06-07 10 views
2

X(おおよそ(1e3,1e3,1e3))があります。Xの操作を行いたい場合、0番目の軸の特定の要素を含めます。第1軸と第2軸)。すなわち、(時には)マスクを出し入れしたい(1e3,1e3)個の要素があります。numpyのマスク配列で効率的なメモリ使用

最も簡単な方法は、

Z = np.zeros_like(X, dtype=bool) 
# assume `inds` is some indexing array which will target 
# the particular (1e3 x 1e3) elements I'm interested in 
Z[inds] = True 
Y = np.ma.masked_array(X, mask=Z) 

、のようなマスクされた配列を構築することだろう。しかし、これは単にマスキング配列にメモリの余分ギガバイトを使用しています。 マスクの要素配列10^9を構築しないと、これを行う方法はありますか?たとえば、マスクのスパース行列を構成することは可能ですか?

+1

Nope; 'scipy.sparse'はどのような種類のマスキングも実装していません。そして 'np、ma'は'疎な '行列を使うことはできません。計算を行う際、np.maはマスクされた値を無害な値(例えば0、1s)で埋めるか、マスクされた値なしで配列を1dに圧縮することに留意してください。適切な場合は、これらのステップを直接実装できます。 – hpaulj

+0

@hpauljありがとう!それはとても役に立ちます。 'np.ma.std'のような関数の場合、マスクされた値はどのように処理されますか? 'axis'引数がない場合、おそらく配列は平坦化されますが、' axis'引数があれば、それは平らにすることも0を埋め込むこともできません。 – DilithiumMatrix

+0

'numpy/ma/core.py'を調べる必要があるようです。 'np.ma.std'はma' std'メソッドを使います。これは 'mean'を使う' var'を使い、 'mean'と' count'を使います。 'ma.sum'は' filled(0) 'を使います。 'count'のように見えるのは、'〜mask 'に 'sum'を使います。すなわち、軸ごとにマスクされていない値を数えます。 – hpaulj

答えて

1

「クリーン」スライスを使用したい場合は、一部の「行」から一部の要素を取り出すだけではなく、マスクの代わりに数値インデックスを使用できます。

例:

arr = np.array([[[1,2,3,4], [5,6,7,8]], [[9,8,9,8], [7,6,7,6]]]) 
sub_idx = np.array([0,2]) 
sub_arr = arr[:, :, sub_idx] 

これはarrのサブセットのコピー、最後の次元において、すなわち0番目と2番目の「スライス」である:定義アレイこと

array([[[1, 3], 
     [5, 7]], 

     [[9, 9], 
     [7, 7]]]) 

注使用するインデックスは1次元であり、メモリ要件が大幅に減少します。

また、これによりコピーが作成されるため、結果に加えた変更(元の配列には変更が加えられていないことに注意してください)を使用することもできます(sub_arr)。 。これを行うには、アレイをコピーし直す必要があります。

sub_arr[:] = 0 # Manipulate the values 
arr[sub_idx] = sub_arr 
+0

ええと、私はちょうどそれらのサブ配列の値を格納することができ、実際にそれらをゼロにして、必要に応じてそれらを置き換えることができると思います...これはすべての状況では機能しません(時には、例えば、標準偏差などを計算するなど) - しかし、それは私の状況ではうまくいくかもしれません。提案のおかげで – DilithiumMatrix

+0

私はあなたがゼロに設定しなければならないと言っているわけではありません - それはサブを操作する私の例でした-アレイ。 – acdr

+0

確かに、しかし、私は、動作する塗りつぶし値がないいくつかの問題があると思います。 – DilithiumMatrix

関連する問題