2016-08-23 74 views
0

我想在numpy數組中找到一個子數組,但是有一個「通配符」。Python/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

使用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) 

我的第一印象是那是一個錯誤。但我必須挖掘更多。

dataA==c是2d,但是面具是1d。

如果我複製c〜3行,然後我得到了想要的結果:

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.equalnp.equal一個蒙面感知版本,一個ufunc版本的元素按元素==運算符。

+0

太棒了!感謝這個詳細的答案。 – louic