In [165]: a
Out[165]:
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
In [166]: mask
Out[166]:
array([[[ True, True, True],
[False, False, False],
[False, False, False]],
[[ True, True, True],
[ True, False, False],
[False, False, False]],
[[ True, True, True],
[ True, True, False],
[False, False, False]]], dtype=bool)
所以a
(和b
)是(3,3),而mask
爲(3,3,3)。
一個布爾掩碼,應用於陣列產生一個1D(當經由where
施加相同):
In [170]: a[mask[1,:,:]]
Out[170]: array([0, 1, 2, 3])
的2D掩碼的where
產生2元素的元組,其可以索引2D陣列:
In [173]: np.where(mask[1,:,:])
Out[173]: (array([0, 0, 0, 1], dtype=int32), array([0, 1, 2, 0], dtype=int32))
在3D掩模where
是一個3元組元素 - 因此too many indices
錯誤:
In [174]: np.where(mask)
Out[174]:
(array([0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2], dtype=int32),
array([0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1], dtype=int32),
array([0, 1, 2, 0, 1, 2, 0, 0, 1, 2, 0, 1], dtype=int32))
讓我們嘗試擴大a
〜3d和敷面膜
In [176]: np.tile(a[None,:],(3,1,1)).shape
Out[176]: (3, 3, 3)
In [177]: np.tile(a[None,:],(3,1,1))[mask]
Out[177]: array([0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4])
值是有的,但它們結合。
我們可以指望的True
數目的mask
每個平面,並用它來split
蒙面瓷磚:
In [185]: mask.sum(axis=(1,2))
Out[185]: array([3, 4, 5])
In [186]: cnt=np.cumsum(mask.sum(axis=(1,2)))
In [187]: cnt
Out[187]: array([ 3, 7, 12], dtype=int32)
In [189]: np.split(np.tile(a[None,:],(3,1,1))[mask], cnt[:-1])
Out[189]: [array([0, 1, 2]), array([0, 1, 2, 3]), array([0, 1, 2, 3, 4])]
內部np.split
使用Python的水平迭代。因此,mask
飛機上的迭代可能會一樣好(在這個小例子中速度提高了6倍)。
In [190]: [a[m] for m in mask]
Out[190]: [array([0, 1, 2]), array([0, 1, 2, 3]), array([0, 1, 2, 3, 4])]
指向與期望的 '矢量',單個陣列(3),(4)和(5)的形狀的基本問題。不同大小的數組是一個強有力的指標,即使不是不可能,真正的「向量化」也很困難。
我不確定這是否做到了你想要的。特別是,'np.where(mask [0])[0]'全部是'真',因爲數組的真值被獲取(如果至少有一個元素爲真,則'真'),而且你使用來自'np.where()'的返回值,我不認爲這是你想要的。 – remram