有效地移动2D numpy子数组

时间:2018-07-23 15:17:13

标签: python python-3.x numpy

我有一个代表灰度图像的numpy数组,例如

image = numpy.array([
    [.0, .0, .0, .0, .1, .3, .5, .0],
    [.0, .0, .0, .0, .4, .4, .6, .0],
    [.0, .0, .0, .0, .3, .3, .7, .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)填充剩余的值。例如,将3x3子数组从(1,5)的中心位置移动到中心位置(3,3)会导致:

numpy.array([
    [.0, .0, .0, .0, .0, .0, .0, .0],
    [.0, .0, .0, .0, .0, .0, .0, .0],
    [.0, .0, .1, .3, .5, .0, .0, .0],
    [.0, .0, .4, .4, .6, .0, .0, .0],
    [.0, .0, .3, .3, .7, .0, .0, .0],
    [.0, .0, .0, .0, .0, .0, .0, .0],
])

有没有一种有效的方法来执行这样的举动?

2 个答案:

答案 0 :(得分:2)

由于您知道要移动的起始索引,因此我们可以使用 np.zeros_like 和numpy索引:

h = w = 3
sub = image[0:0+w,4:4+h]
out = np.zeros_like(image)

然后分配:

out[2:2+w, 2:2+h] = sub

输出:

array([[0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ],
       [0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ],
       [0. , 0. , 0.1, 0.3, 0.5, 0. , 0. , 0. ],
       [0. , 0. , 0.4, 0.4, 0.6, 0. , 0. , 0. ],
       [0. , 0. , 0.3, 0.3, 0.7, 0. , 0. , 0. ],
       [0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ]])

答案 1 :(得分:1)

这是使用自定义函数的一种方法。 “中心”的概念仅被很好地定义为奇数长度的整数坐标,例如: (3 x 3);我的回答也仅限于方块。

def mover(A, c_in, c_out, size):
    side = int((size - 1) / 2)
    arr = A[c_in[0]-side: c_in[0]+side+1, c_in[1]-side: c_in[1]+side+1]
    res = np.zeros(shape=A.shape)
    res[c_out[0]-side: c_out[0]+side+1, c_out[1]-side: c_out[1]+side+1] = arr
    return res

centre_in = (1, 5)
centre_out = (3, 3)
size = 3

res = mover(image, centre_in, centre_out, size)

array([[ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ],
       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ],
       [ 0. ,  0. ,  0.1,  0.3,  0.5,  0. ,  0. ,  0. ],
       [ 0. ,  0. ,  0.4,  0.4,  0.6,  0. ,  0. ,  0. ],
       [ 0. ,  0. ,  0.3,  0.3,  0.7,  0. ,  0. ,  0. ],
       [ 0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. ]])