屏蔽数组中的特定值

时间:2016-12-25 05:38:48

标签: python arrays numpy membership

示例:

我有一个数组:

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中执行此操作的最简单方法是什么?

3 个答案:

答案 0 :(得分: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)

2018年版:numpy.isin

使用NumPy内置的np.isin(在1.13.0中引入)保持形状,因此不需要我们重新塑造 -

In [153]: np.isin(a,[2,3])
Out[153]: 
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]])

答案 1 :(得分: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的大小),则相对较快。实际上对于小arr2np.in1d执行此操作:

        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)

答案 2 :(得分: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]]