根据第3个ndarray中提供的偏移量在2个ndarray之间移动项目

时间:2018-03-16 15:29:37

标签: python python-3.x numpy-ndarray

为了计算由opencv提供的(4000,6000,3)形状的ndarrays中存储的图像,我想将值从源ndarray复制到目标中不同坐标(x,y)的目标ndarray。要添加到源坐标以便计算目标坐标的偏移量存储在ndarray中。 请参阅下面使用两个嵌套循环实现的简单原则:

import numpy as np

source = np.array([
[1,2,3,33],
[4,5,6,66],
[7,8,9,99]])

target = np.array([
[0,0,0,0],
[0,0,0,0],
[0,0,0,0]])

move_instruction = np.array([
                [[0,0],[0,0],[0,0],[0,0]],
                [[-1,0],[0,0],[1,1],[0,0]],
                [[0,0],[0,0],[0,0],[0,0]]])

rows, cols = source.shape
for y in range(rows):
    for x in range(cols):
       y_target = y + move_instruction[y][x][0]
       x_target = x + move_instruction[y][x][1]
       target[y_target][x_target] = source[y][x]

问题是它很慢。

我初学numpy并想知道是否有一种聪明的方法以更有效的方式使用ndarray操作执行此操作?

1 个答案:

答案 0 :(得分:0)

您可以获取源数组的所有索引,将移位添加到这些索引,然后在目标上的移位索引的位置处分配源的值。

import numpy as np

source = np.array([
[1,2,3,33],
[4,5,6,66],
[7,8,9,99]])

target = np.zeros_like(source)

move_instruction = np.array([
                [[0,0],[0,0],[0,0],[0,0]],
                [[-1,0],[0,0],[1,1],[0,0]],
                [[-100,100],[-100,0],[0,100],[0,0]]])

all_inds = np.where(np.ones_like(source))
moves = move_instruction[all_inds]
new_r = all_inds[0] + moves[...,0]
new_c = all_inds[1] + moves[...,1]
arr_shape = source.shape

# Filter for invalid shifts
filter = (new_r < 0) + (new_r >= arr_shape[0]) + (new_c < 0) + (new_c >= arr_shape[1])
new_r[filter] = all_inds[0][filter] # This just recovers the original non-moved index;
new_c[filter] = all_inds[1][filter] # if you want to do something else you'll have to
                                    # modify these indices some other way.
new_inds = (new_r, new_c)
target[new_inds] = source[all_inds]