7

実際のインデックス値に基づいて配列をマスクするにはどうすればよいですか?

つまり、10 x 10 x 30 の行列があり、最初と 2 番目のインデックスが互いに等しいときに配列をマスクしたい場合です。

たとえば、[1, 1 , :] 1 と 1 は等しいためマスクする必要がありますが、等しく[1, 2, :]ないためマスクする必要はありません。

私は現在の問題に似ており、物事を複雑にする可能性があるため、3次元でのみこれを求めています. しかし、私の主な質問は、インデックスの値に基づいて配列をマスクする方法ですか?

4

2 に答える 2

7

一般に、インデックスの値にアクセスするには、次を使用できますnp.meshgrid

i, j, k = np.meshgrid(*map(np.arange, m.shape), indexing='ij')
m.mask = (i == j)

この方法の利点はi、 、j、およびの任意のブール関数に対して機能することkです。identity特殊なケースを使用するよりも少し遅くなります。

In [56]: %%timeit
   ....: i, j, k = np.meshgrid(*map(np.arange, m.shape), indexing='ij')
   ....: i == j
10000 loops, best of 3: 96.8 µs per loop

@Jaime が指摘しているようにmeshgrid、オプションをサポートしていsparseます。このオプションはあまり複製を行いませんが、ブロードキャストしないため、場合によってはもう少し注意が必要です。これにより、メモリが節約され、処理が少し高速化されます。例えば、

In [77]: x = np.arange(5)

In [78]: np.meshgrid(x, x)
Out[78]: 
[array([[0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4]]),
 array([[0, 0, 0, 0, 0],
       [1, 1, 1, 1, 1],
       [2, 2, 2, 2, 2],
       [3, 3, 3, 3, 3],
       [4, 4, 4, 4, 4]])]

In [79]: np.meshgrid(x, x, sparse=True)
Out[79]: 
[array([[0, 1, 2, 3, 4]]),
 array([[0],
       [1],
       [2],
       [3],
       [4]])]

したがって、sparse彼が言うようにバージョンを使用できますが、そのようにブロードキャストを強制する必要があります。

i, j, k = np.meshgrid(*map(np.arange, m.shape), indexing='ij', sparse=True)
m.mask = np.repeat(i==j, k.size, axis=2)

そしてスピードアップ:

In [84]: %%timeit
   ....: i, j, k = np.meshgrid(*map(np.arange, m.shape), indexing='ij', sparse=True)
   ....: np.repeat(i==j, k.size, axis=2)
10000 loops, best of 3: 73.9 µs per loop
于 2013-09-17T22:28:42.840 に答える
0

対角線をマスクしたいという特殊なケースでは、対角線にnp.identity()沿って 1 を返す関数を使用できます。3 番目の次元があるため、その 3 番目の次元を恒等行列に追加する必要があります。

m.mask = np.identity(10)[...,None]*np.ones((1,1,30))

その配列を構築するより良い方法があるかもしれませんが、それは基本的にnp.identity(10)配列の 30 を積み重ねています。たとえば、これは同等です。

np.dstack((np.identity(10),)*30)

しかし遅い:

In [30]: timeit np.identity(10)[...,None]*np.ones((1,1,30))
10000 loops, best of 3: 40.7 µs per loop

In [31]: timeit np.dstack((np.identity(10),)*30)
1000 loops, best of 3: 219 µs per loop

そして@Ophionの提案

In [33]: timeit np.tile(np.identity(10)[...,None], 30)
10000 loops, best of 3: 63.2 µs per loop

In [71]: timeit np.repeat(np.identity(10)[...,None], 30)
10000 loops, best of 3: 45.3 µs per loop
于 2013-09-17T22:12:48.303 に答える