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

Move items between 2 ndarrays based on offset provided in a 3rd ndarray

为了计算存储在 opencv 提供的 ndarrays 中的图像 (4000,6000,3) 形状,我想将值从源 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 操作执行此操作?

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

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]