在numpy中使用掩码将2d数组分配给4d数组

neskvpey  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(118)

我有一个大小为(H,W,H-h+1,W-w+1)的4d掩码,其中mask[:,:,dh,dw]表示从图像左上角偏移(dh,dw)的大小为hxw的滑动窗口的掩码。
范例:

>>> mask[:,:,0,0]
array([[1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
       [1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
       [1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
       [1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

>>> mask[:,:,1,1]
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
       [0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
       [0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
       [0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

字符串
我想把一些大小为hxw的矩阵放在用mask表示的位置上。我的问题是我不知道如何将一个2d数组分配给一个4d掩码的4d数组。
例如,对于矩阵

array([[ 1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10],
       [11, 12, 13, 14, 15],
       [16, 17, 18, 19, 20]])


对于移位(0,0),我期望的结果是

>>> result[:,:,0,0]
array([[1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0],
       [6, 7, 8, 9, 10, 0, 0, 0, 0, 0, 0, 0],
       [11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0],
       [16, 17, 18, 19, 20, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

lnvxswe2

lnvxswe21#

我不知道numpy是否有一个简单的方法来做这个,如果这是绝对必要的,我不能帮助你!
如果你不介意直接索引,你可以使用一些神奇的巫术艺术;),如下所示:

# Setup
import numpy as np
from numpy.lib.stride_tricks import sliding_window_view as swv

H, W, h, w = 10, 12, 4, 5
out = np.zeros((H, W, H - h + 1, W - w + 1), dtype=int)
arr = np.arange(1, h * w + 1).reshape(h, w)

# Create an index for each dimension
# a = [0, 1, ..., 10]
# b = [0, 1, ..., 12]
# etc...
a, b, c, d = map(np.arange, out.shape)

# Index the output array with 4 indexers:
out[
    swv(a, h)[:, None, :, None],  # Use a sliding index for the
    swv(b, w)[None, :, None, :],  # first two dimensions.
    c[:, None, None, None],       # Index the latter two dimensions normally, except
    d[None, :, None, None],       # such that they broadcast with the sliding windows.
] = arr                           # Assign your array to the indexed output

字符串
一些产出:

>>> out[:, :, 1, 1]
array([[ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0],
       [ 0,  1,  2,  3,  4,  5,  0,  0,  0,  0,  0,  0],
       [ 0,  6,  7,  8,  9, 10,  0,  0,  0,  0,  0,  0],
       [ 0, 11, 12, 13, 14, 15,  0,  0,  0,  0,  0,  0],
       [ 0, 16, 17, 18, 19, 20,  0,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0]])
>>> out[:, :, 4, 6]
array([[ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  1,  2,  3,  4,  5,  0],
       [ 0,  0,  0,  0,  0,  0,  6,  7,  8,  9, 10,  0],
       [ 0,  0,  0,  0,  0,  0, 11, 12, 13, 14, 15,  0],
       [ 0,  0,  0,  0,  0,  0, 16, 17, 18, 19, 20,  0],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0]])

20jt8wwn

20jt8wwn2#

设置一个较小的情况下,与(4,4,2,2)面具。(2,2)大小只是为了演示的目的。
我们要插入的(2,2)数组:

n [54]: arr= np.arange(1,5).reshape(2,2)

字符串
掩码,只有2个子数组集合。不管它是bool还是int。int版本显示更多complex:

In [55]: mask = np.zeros((4,4,2,2),int)    
In [56]: mask[:2,:2,0,0]=1; mask[1:3,1:3,1,1]=1

In [57]: mask[:,:,1,1]
Out[57]: 
array([[0, 0, 0, 0],
       [0, 1, 1, 0],
       [0, 1, 1, 0],
       [0, 0, 0, 0]])


目标数组-与掩码大小相同:

In [58]: res = np.zeros(mask.shape,int)


我认为,非零的,where`,索引比bool掩码更有用:

In [59]: idx = np.nonzero(mask)    
In [60]: idx
Out[60]: 
(array([0, 0, 1, 1, 1, 1, 2, 2], dtype=int64),
 array([0, 1, 0, 1, 1, 2, 1, 2], dtype=int64),
 array([0, 0, 0, 0, 1, 1, 1, 1], dtype=int64),
 array([0, 0, 0, 0, 1, 1, 1, 1], dtype=int64))


这8个非零值从res中选择8个元素:

In [61]: res[idx]
Out[61]: array([0, 0, 0, 0, 0, 0, 0, 0])


复制arr来匹配。我不经常使用resize,但在这里它只是我想要的:

In [62]: arr1=np.resize(arr,idx[0].shape);arr1
Out[62]: array([1, 2, 3, 4, 1, 2, 3, 4])    
In [63]: res[idx]=arr1


检查结果:

In [64]: res[:,:,0,0]
Out[64]: 
array([[1, 2, 0, 0],
       [3, 4, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0]])

In [65]: res[:,:,1,1]
Out[65]: 
array([[0, 0, 0, 0],
       [0, 1, 2, 0],
       [0, 3, 4, 0],
       [0, 0, 0, 0]])


在我所演示的和其他答案之间可能有很多重叠之处,但我试图让事情直接和简单。

相关问题