2016-12-25 6 views
3

例から特定の値をマスク:アレイ

Iは、配列を有する:

array([[1, 2, 0, 3, 4], 
     [0, 4, 2, 1, 3], 
     [4, 3, 2, 0, 1], 
     [4, 2, 3, 0, 1], 
     [1, 0, 2, 3, 4], 
     [4, 3, 2, 0, 1]], dtype=int64) 

を私が "悪い" の値の組(可変長、順序は問わない)を有しています

{2, 3} 

私はこれらの値を隠すマスクを返すようにしたい:

array([[False, True, False, True, False], 
     [False, False, True, False, True], 
     [False, True, True, False, False], 
     [False, True, True, False, False], 
     [False, False, True, True, False], 
     [False, True, True, False, False]], dtype=bool) 

NumPyでこれを行う最も簡単な方法は何ですか?

答えて

4

使用np.in1dそうのように、私たちは、このようなマッチングの発生の平坦化されたマスクを与え、その後、所望の出力のために戻って、入力配列の形に作り変えます -

np.in1d(a,[2,3]).reshape(a.shape) 

サンプル実行 -

In [5]: a 
Out[5]: 
array([[1, 2, 0, 3, 4], 
     [0, 4, 2, 1, 3], 
     [4, 3, 2, 0, 1], 
     [4, 2, 3, 0, 1], 
     [1, 0, 2, 3, 4], 
     [4, 3, 2, 0, 1]]) 

In [6]: np.in1d(a,[2,3]).reshape(a.shape) 
Out[6]: 
array([[False, True, False, True, False], 
     [False, False, True, False, True], 
     [False, True, True, False, False], 
     [False, True, True, False, False], 
     [False, False, True, True, False], 
     [False, True, True, False, False]], dtype=bool) 
1

これより簡単な方法があるかもしれません。しかし、これは一方通行になります

import numpy as np 

a = np.array([[1, 2, 0, 3, 4], 
     [0, 4, 2, 1, 3], 
     [4, 3, 2, 0, 1], 
     [4, 2, 3, 0, 1], 
     [1, 0, 2, 3, 4], 
     [4, 3, 2, 0, 1]], dtype=np.int64) 

f = np.vectorize(lambda x: x in {2,3}) 
print f(a) 

出力:

[[False True False True False] 
[False False True False True] 
[False True True False False] 
[False True True False False] 
[False False True True False] 
[False True True False False]] 
+1

は 'vectorize'はしかしちょうど' for'ループで、それはないですか?小さなarr2のため実際には、np.in1dはこれを行いますか – endolith

3
In [965]: np.any([x==i for i in (2,3)],axis=0) 
Out[965]: 
array([[False, True, False, True, False], 
     [False, False, True, False, True], 
     [False, True, True, False, False], 
     [False, True, True, False, False], 
     [False, False, True, True, False], 
     [False, True, True, False, False]], dtype=bool) 

(2,3)のセットが小さい場合(これはxのサイズと比較して)、これは比較的高速です。

 mask = np.zeros(len(ar1), dtype=np.bool) 
     for a in ar2: 
      mask |= (ar1 == a) 

このからマスクされた配列を作る:

In [970]: np.ma.MaskedArray(x,mask) 
Out[970]: 
masked_array(data = 
[[1 -- 0 -- 4] 
[0 4 -- 1 --] 
[4 -- -- 0 1] 
[4 -- -- 0 1] 
[1 0 -- -- 4] 
[4 -- -- 0 1]], 
      mask = 
[[False True False True False] 
[False False True False True] 
[False True True False False] 
[False True True False False] 
[False False True True False] 
[False True True False False]], 
     fill_value = 999999) 
+1

'(2,3)]'の '[x == i]は、最終出力よりもN倍のメモリを占有します.Nは検索配列内のelemsの数です。 Askersは、正確に小さな入力を処理しているとは限らない、特にパフォーマンスを求めているときに、サンプルを投稿します。 – Divakar

+0

'in1d'のループに相当するより大きなメモリ使用量が節約されます。おそらく同じスピードです。しかし、私たちはテストしなければならないでしょう。すべてのケースで最適なソリューションではないかもしれませんが、良い基本ソリューションだと思います。 – hpaulj

+0

ええ、 'np.in1d'で関数ラッパーのオーバーヘッドがあると思いますが、ほとんど私が思うに匹敵するパフォーマンスです。 – Divakar