Multiplying a numpy array with another numpy array at a specific index

For ease of explanation I will be using 2-dimensional numpy arrays (I am using 3-dimensional arrays in my problem).

I have 2 arrays, one records the odds of something occuring at those specific coordinates. The other array is a pre-generated matrix that is used to lower the values of the first array around a central point in a pre-determined radius.

I want to automatically select points in the first matrix (henceforth A), and prevent the program to select another point that sits too close to previously selected points. So I want to multiply the values around the selected point related to the distance from said point.

E.G.:

Matrix A:

[[0, 0, 0, 0, 0, 0],
 [0, 1, 2, 2, 1, 0],
 [0, 2, 4, 4, 2, 0],
 [0, 2, 4, 4, 2, 0],
 [0, 1, 2, 2, 1, 0],
 [0, 0, 0, 0, 0, 0]]

Matrix B:

[[ 1, 0.5, 1 ],
 [0.5, 0, 0.5],
 [ 1, 0.5, 1 ]]

Now say that index [2, 1] is selected as a point of interest. B is multiplied with A, but only with the values in a 3*3 around [2, 1]

Result:

[[0,  0,  0, 0, 0, 0],
 [0, 0.5, 0, 1, 1, 0],
 [0,  2,  2, 4, 2, 0],
 [0,  2,  4, 4, 2, 0],
 [0,  1,  2, 2, 1, 0],
 [0,  0,  0, 0, 0, 0]]

This should result in the points around [2, 1] not being valuable enough to be selected as points of interest, unless the conditions are high enough to be selected anyway, hence the multiplication.

Now, I can’t seem to figure out a way to perform this specific multiplication. numpy.multiply() would repeat B so that it gets applied over the entire matrix A while I only want to apply it on a small part of A.

Another option would be looping over the affected section of Matrix A, but this requires an insane amount of time (especially in 3-dimensional matrices)

In other words, I want to apply a convolution filter without summing up the multiplication results at the end, but apply them to the underlying values of the convolved matrix (A)

Any insights on this issue are appreciated.

Answer

The easiest solution uses slicing:

A[5:8, 8:11] = np.multiply(A[5:8,8:11], B)

What this does is extract from A the 3×3 area around the selected point (here [6,9]), multiply it (element-wise) by B, and write it back at the same location.


Since you talked about convolution, if you want to use that the approach would be to create a matrix M of the same shape as A, but that is zero everywhere except at the selected point. This matrix you can convolve with B, and then multiply with A:

M = np.zeros(A.shape)
M[6,9] = 1
M = scipy.ndimage.filters.convolve(M, B)
A = np.multiply(A, M)

(or something to that extent, I did not test this variant).

Leave a Reply

Your email address will not be published. Required fields are marked *