Python 以给定索引为中心添加 2 个大小不均的二维数组

Python add up 2 unevenly sized 2d arrays at given index as center

给定 2 个数组,例如:

main_arr = np.array([
    [0, 0, 0, 0, 0],
    [0, 1, 0, 0, 0],
    [0, 0, 0, 0, 0],
    [0, 0, 0, 1, 0],
    [0, 0, 0, 0, 0]
])

small_arr = np.array([
    [2, 2, 2],
    [2, 0, 2],
    [2, 2, 2]
])

result_arr = np.array([
    [2, 2, 2, 0, 0],
    [2, 1, 2, 0, 0],
    [2, 2, 4, 2, 2],
    [0, 0, 2, 1, 2],
    [0, 0, 2, 2, 2]
])

如何有效地将 small_arr 添加到 main_arr 中,其中合并中心是某个已知索引(在这个例子中是第一个)。这个操作有什么方便的工具吗?

在我的具体案例中,我有数十万个索引并且需要执行相同的操作。因此,理想情况下,解决方案应该是遍历索引集的循环过程。

二维卷积

仅简单示例 0/1

如果要在有 1 的位置添加值,请使用 2D 卷积:

from scipy.signal import convolve2d
out = convolve2d(main_arr, small_arr, mode='same')+main_arr

输出:

array([[2, 2, 2, 0, 0],
       [2, 1, 2, 0, 0],
       [2, 2, 4, 2, 2],
       [0, 0, 2, 1, 2],
       [0, 0, 2, 2, 2]])
更复杂的例子
main_arr  = np.array([
    [1, 0, 0, 9, 0],
    [0, 0, 0, 0, 0],
    [0, 9, 0, 0, 0],
    [0, 0, 0, 1, 0],
    [-1, 0, 0, 0, 0]
])

small_arr = np.array([
    [2, 2, 2],
    [2, 0, 2],
    [2, 2, 2]
])

from scipy.signal import convolve2d

convolve2d((main_arr==1).astype(bool), small_arr, mode='same')+main_arr

输出:

array([[ 1,  2,  0,  9,  0],
       [ 2,  2,  0,  0,  0],
       [ 0,  9,  2,  2,  2],
       [ 0,  0,  2,  1,  2],
       [-1,  0,  2,  2,  2]])

较早的回答

假设你想从位置 0,0 和 2,2 相加,你可以使用:

main_arr  = np.array([
    [0, 0, 0, 0, 0],
    [0, 1, 0, 0, 0],
    [0, 0, 0, 0, 0],
    [0, 0, 0, 1, 0],
    [0, 0, 0, 0, 0]
])

small_arr = np.array([
    [2, 2, 2],
    [2, 0, 2],
    [2, 2, 2]
])

x,y = small_arr.shape
main_arr[0:x, 0:y] += small_arr    # actually main_arr[0:0+x, 0:0+y]
main_arr[2:2+x, 2:2+y] += small_arr

输出:

array([[2, 2, 2, 0, 0],
       [2, 1, 2, 0, 0],
       [2, 2, 4, 2, 2],
       [0, 0, 2, 1, 2],
       [0, 0, 2, 2, 2]])

我假设 small_arr 总是正方形,尺寸为奇数(所以我们有一个中心)。

indexes = [(1,1), (3,3)]
offset = small_arr.shape[0] // 2
for x, y in indexes:
  main_arr[x-offset:x+offset+1, y-offset:y+offset+1] += small_arr

正如评论中所指出的,这仍然无法解决您的索引位于 main_arr 的“边界上”的情况。

由于您已经知道指标,因此您只需遍历与该指标相邻的每个仓位。所以你必须首先使用索引找到坐标,这将是一个元组列表。假设小数组始终是一个 3x3 矩阵,您可以执行以下操作:

coordinates = [(x_1,y_1), ... , (x_n,y_n)]

for(co in coordinates) {

  x = co[0]
  y = co[1]
  result_arr[x][y + 1] = result_arr[x][y + 1] + small_arr[x][y + 1]
  result_arr[x][y - 1] = result_arr[x][y - 1] + small_arr[x][y - 1]
  result_arr[x + 1][y] = result_arr[x + 1][y] + small_arr[x + 1][y]
  result_arr[x + 1][y + 1] = result_arr[x + 1][y + 1] + small_arr[x + 1][y + 1]
  result_arr[x + 1][y - 1] = result_arr[x + 1][y - 1] + small_arr[x + 1][y - 1]
  result_arr[x - 1][y] = result_arr[x - 1][y] + small_arr[x - 1][y]
  result_arr[x - 1][y + 1] = result_arr[x - 1][y + 1] + small_arr[x - 1][y + 1]
  result_arr[x - 1][y - 1] = result_arr[x - 1][y - 1] + small_arr[x - 1][y - 1]