2017-10-17 9 views
1

この出力を得るためにnumpyでマスクを適用する方法は?numpyで配列から別の行列にマスクを適用する方法

ar2 = np.arange(1,26)[::-1].reshape([5,5]).T 
ar3 = np.array([1,1,-1,-1,1]) 
print ar2, '\n\n', ar3 

[[25 20 15 10 5] 
[24 19 14 9 4] 
[23 18 13 8 3] 
[22 17 12 7 2] 
[21 16 11 6 1]] 

[ 1 1 -1 -1 1] 

は--apply AR3 = 1場所:ar2/ar2[:,0][:, np.newaxis]

--apply AR3 = -1場所:ar2/ar2[:,4][:, np.newaxis]

結果は、私がされた後、午前:

[[1 0 0 0 0] 
[1 0 0 0 0] 
[ 7 6 4 2 1] 
[11 8 6 3 1] 
[1 0 0 0 0]] 

私が持っています試しましたnp.where()

答えて

3

np.whereはここで働いてはならない理由私は表示されません。

>>> np.where((ar3==1)[:, None], 
...   ar2 // ar2[:, [0]], # where condition is True, divide by first column 
...   ar2 // ar2[:, [4]]) # where condition is False, divide by last column 
array([[ 1, 0, 0, 0, 0], 
     [ 1, 0, 0, 0, 0], 
     [ 7, 6, 4, 2, 1], 
     [11, 8, 6, 3, 1], 
     [ 1, 0, 0, 0, 0]]) 

私が代わりに通常の除算(/)の私は//(床部門)を使用した理由だのPython 3を使用していそう結果に浮動小数点数が含まれます。

これは配列を熱心に計算するので、すべての値に対してar2 // ar2[:, [0]]ar2 // ar2[:, [4]]と評価されます。メモリ内にar2のサイズの3つの配列を効果的に保持する(結果と2つの一時的な)。あなたはそれがより多くのメモリ効率たい場合は、操作を行う前にマスクを適用しますする必要があります。

>>> res = np.empty_like(ar2) 
>>> mask = ar3 == 1 
>>> res[mask] = ar2[mask] // ar2[mask][:, [0]] 
>>> res[~mask] = ar2[~mask] // ar2[~mask][:, [4]] 
>>> res 
array([[ 1, 0, 0, 0, 0], 
     [ 1, 0, 0, 0, 0], 
     [ 7, 6, 4, 2, 1], 
     [11, 8, 6, 3, 1], 
     [ 1, 0, 0, 0, 0]]) 

をこれは、より少ないメモリを使用しています(そして、あまりにも、おそらく高速です)のみ必要な値を計算します。

2

最もエレガントではありませんが、ここにあります私が考えることができるもの。

m = ar3 == -1 
a = (ar2 // ar2[:, [0]]) 
a[m] = (ar2 // ar2[:, [4]])[m] 

print(a) 
array([[ 1, 0, 0, 0, 0], 
     [ 1, 0, 0, 0, 0], 
     [ 7, 6, 4, 2, 1], 
     [11, 8, 6, 3, 1], 
     [ 1, 0, 0, 0, 0]], dtype=int32) 
関連する問題