web-dev-qa-db-ja.com

numpy 2D配列を適切にマスクする方法は?

次のような2次元の座標配列があるとします

x = array([[1,2],[2,3],[3,4]])

以前の私の仕事では、次のようなマスクを生成していました

_mask = [False,False,True]_

2D座標ベクトルでこのマスクを使用しようとすると、エラーが発生します

_newX = np.ma.compressed(np.ma.masked_array(x,mask))

>>>numpy.ma.core.MaskError: Mask and data not compatible: data size 
   is 6, mask size is 3.`
_

理にかなっていると思います。そのため、代わりに次のマスクを単純に使用しようとしました。

_mask2 = np.column_stack((mask,mask))
newX = np.ma.compressed(np.ma.masked_array(x,mask2))
_

そして私が得るものは近いです:

>>>array([1,2,2,3])

私が期待する(そして欲しい)ものに:

>>>array([[1,2],[2,3]])

これを行う簡単な方法が必要ですか?

18
Anonymous

これはあなたが探しているものですか?

import numpy as np
x[~np.array(mask)]
# array([[1, 2],
#        [2, 3]])

または numpy masked array :から

newX = np.ma.array(x, mask = np.column_stack((mask, mask)))
newX

# masked_array(data =
#  [[1 2]
#  [2 3]
#  [-- --]],
#              mask =
#  [[False False]
#  [False False]
#  [ True  True]],
#        fill_value = 999999)
12
Psidom

あなたのxは3x2です:

_In [379]: x
Out[379]: 
array([[1, 2],
       [2, 3],
       [3, 4]])
_

3要素のブールマスクを作成します。

_In [380]: rowmask=np.array([False,False,True])
_

これを使用して、TrueまたはFalseの行を選択できます。どちらの場合でも、結果は2dです。

_In [381]: x[rowmask,:]
Out[381]: array([[3, 4]])

In [382]: x[~rowmask,:]
Out[382]: 
array([[1, 2],
       [2, 3]])
_

これは、MaskedArrayサブクラスを使用しません。このような配列を作成するには、形状がxに一致するマスクが必要です。 1つのディメンションだけをマスクすることはできません。

_In [393]: xmask=np.stack((rowmask,rowmask),-1)  # column stack

In [394]: xmask
Out[394]: 
array([[False, False],
       [False, False],
       [ True,  True]], dtype=bool)

In [395]: np.ma.MaskedArray(x,xmask)
Out[395]: 
masked_array(data =
 [[1 2]
 [2 3]
 [-- --]],
             mask =
 [[False False]
 [False False]
 [ True  True]],
       fill_value = 999999)
_

compressedを適用すると、解かれた配列が生成されます:array([1, 2, 2, 3])

マスキングは要素ごとに行われるため、行1の1つの要素、行2の2などをマスクできます。そのため、一般的に、マスクされた要素を削除するcompressingは2D配列を生成しません。一般的な選択肢は、フラット化されたフォームのみです。

_np.ma_は、マスクされた値のばらつきがある場合に最も意味があります。行全体または列全体を選択または選択解除する場合は、あまり価値がありません。

===============

より一般的なマスク配列は次のとおりです。

_In [403]: np.ma.masked_inside(x,2,3)
Out[403]: 
masked_array(data =
 [[1 --]
 [-- --]
 [-- 4]],
             mask =
 [[False  True]
 [ True  True]
 [ True False]],
       fill_value = 999999)

In [404]: np.ma.masked_equal(x,2)
Out[404]: 
masked_array(data =
 [[1 --]
 [-- 3]
 [3 4]],
             mask =
 [[False  True]
 [ True False]
 [False False]],
       fill_value = 2)

In [406]: np.ma.masked_outside(x,2,3)
Out[406]: 
masked_array(data =
 [[-- 2]
 [2 3]
 [3 --]],
             mask =
 [[ True False]
 [False False]
 [False  True]],
       fill_value = 999999)
_
5
hpaulj

これらの解決策はどれも役に立たなかったので、私は解決策が何をしたかを書き留めようと思った。 python 3.xを使用し、2つの3D配列で作業しました。1つはdata_3Dと呼び、脳スキャンでの記録の浮動小数点値が含まれ、もう1つはtemplate_3Dには脳の領域を表す整数が含まれていますが、data_3Dに従って整数region_codeに対応するtemplate_3Dからこれらの値を選択したかったのです。

my_mask = np.in1d(template_3D, region_code).reshape(template_3D.shape)
data_3D_masked = data_3D[my_mask]

これにより、関連する記録のみの1D配列が得られます。

2
CrossEntropy

最後の例では、問題はマスクではありません。 compressedの使用です。 compressedのdocstringから:

Return all the non-masked data as a 1-D array.

したがって、compressedは、マスクされていない値を1次元配列に平坦化します。 (圧縮されたデータがn次元構造を持つという保証がないためです。)

マスク配列を圧縮する前に見てください。

In [8]: np.ma.masked_array(x, mask2)

Out[8]: 
masked_array(data =
 [[1 2]
 [2 3]
 [-- --]],
             mask =
 [[False False]
 [False False]
 [ True  True]],
       fill_value = 999999)
1