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

Time:04-29

Given 2 arrays, for example:

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]
])

How to efficiently add up small_arr into the main_arr where center for merging is some known index (in this example number ones).Is there is any handy tool for this operation?

In my specific case, I have hundreds of thousands of indexes and need to perform this same operation. So ideally the solution should be looping process that runs through the set of indexes.

CodePudding user response:

2D convolution

simple example 0/1 only

If you want to add the values where you have the 1s, use a 2D convolution:

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

output:

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]])
more complex example
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

output:

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]])

older answer

Assuming you want to add from the positions 0,0 and 2,2, you could use:

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

output:

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]])

CodePudding user response:

I'll assume small_arr is always square, with an odd dimension (so we have a center).

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

As pointed out in the comments, this still not solve case where your index is "on the border" of main_arr.

CodePudding user response:

Since you already know the indicies, you just have to go over every position that is a neighbor of that index. So you have to find the coordinates using the indices first, which will be a list of tuples. Assuming the small array always is a 3x3 matrix, you can do the following:

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] 
  • Related