Python / NumPy第一次出现掩码子阵

时间:2016-08-23 23:26:07

标签: python arrays numpy

我想在numpy数组中找到子数组的出现,但是带有“通配符”。

a = np.array([1, 2, 3, 4, 5])
b = np.ma.array([2, 99, 4], mask=[0, 1, 0])

这个想法是在a中搜索b会给出匹配,因为99被屏蔽了。

更具体地说,我希望所描述的方法here可行,但它不会:

def rolling_window(a, size):
    shape = a.shape[:-1] + (a.shape[-1] - size + 1, size)
    strides = a.strides + (a. strides[-1],)
    return np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)

a = np.array([1, 2, 3, 4, 5])
b = np.array([2, 3, 4])
c = np.ma.array([2, 99, 4], mask=[0, 1, 0])

workingMatch = rolling_window(a, len(b)) == b
notWorkingMatch = rolling_window(a, len(c)) == c

这导致

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

>>> notWorkingMatch
masked_array(data = [[False False False]
                     [-- -- --]
                     [False False False]],
             mask = [False  True False], fill_value = True)

...所以找不到匹配项。为什么不? (我想学点东西) 如何使这项工作?

1 个答案:

答案 0 :(得分:1)

使用np.ma.equal代替== - 请参阅结束。

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

屏蔽数组由data数组和掩码数组组成。掩蔽阵列通常用于填充'掩盖的值与无害的东西,或通过压缩它们。我不完全确定这次==测试会发生什么,但让我们看一下计算。

你的跨步会产生一个数组:

In [614]: A
Out[614]: 
array([[1, 2, 3],
       [2, 3, 4],
       [3, 4, 5]])

In [615]: b
Out[615]: array([2, 3, 4])

In [612]: A==b
Out[612]: 
array([[False, False, False],
       [ True,  True,  True],
       [False, False, False]], dtype=bool)

蒙面数组包含datamask

In [616]: c
Out[616]: 
masked_array(data = [2 -- 4],
             mask = [False  True False],
       fill_value = 999999)
In [617]: c.data
Out[617]: array([ 2, 99,  4])
In [618]: c.mask
Out[618]: array([False,  True, False], dtype=bool)
In [619]: (A==c).data
Out[619]: 
array([[False, False, False],
       [ True, False,  True],
       [False, False, False]], dtype=bool)

data我们期待A==c.data。中心99不匹配。

但看起来掩码应用于整个布尔数组,就像c列数组一样 - 它掩盖第二行而不是第二列。

In [624]: A==c
Out[624]: 
masked_array(data =
 [[False False False]
 [-- -- --]
 [False False False]],
             mask =
 [False  True False],
       fill_value = True)

我的第一印象是这是一个错误。但是我还要挖掘更多。

data的{​​{1}}为2d,但掩码为1d。

如果我将A==c复制到3行,那么我会得到所需的结果:

c

我不知道是否有更清洁的方法,但它表明解决方案需要采取的方向。

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

In [638]: c[None,:]*np.array([1,1,1])[:,None] Out[638]: masked_array(data = [[2 -- 4] [2 -- 4] [2 -- 4]], mask = [[False True False] [False True False] [False True False]], fill_value = 999999) In [639]: c1=c[None,:]*np.array([1,1,1])[:,None] In [640]: A==c1 Out[640]: masked_array(data = [[False -- False] [True -- True] [False -- False]], mask = [[False True False] [False True False] [False True False]], fill_value = True) In [641]: (A==c1).all(axis=1) Out[641]: masked_array(data = [False True False], mask = [False False False], fill_value = True) 做我们想要的事情(np.ma.equal与正确的面具比较)

==

In [645]: np.ma.equal(A,c) Out[645]: masked_array(data = [[False -- False] [True -- True] [False -- False]], mask = [[False True False] [False True False] [False True False]], fill_value = 999999) In [646]: np.ma.equal(A,c).any(axis=1) Out[646]: masked_array(data = [False True False], mask = [False False False], fill_value = True) np.ma.equal的屏蔽感知版本,元素np.equal运算符的ufunc版本。