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]