Reputation: 1768
I am trying to replace values in a numpy matrix which are below a certain threshold with the average of the values of matrix cells which are near the concerned cells (i.e. the ones with values below the threshold.
As an example, let's consider this 10*10 matrix (say matrx
):
matrx = np.array([[1,4,9,2,2,5,1,1,9,1],[2,4,3,5,2,2,1,2,1,1],
[3,4,-2,-3,4,2,3,5,1,2],[2,3,-3,-5,3,3,7,8,-4,1],[3,4,2,3,4,2,3,7,3,2],
[1,4,9,3,4,3,3,2,9,4],[2,1,3,5,2,2,3,2,3,3],
[3,6,8,3,7,2,3,5,3,2],[5,-2,-3,5,2,3,7,8,4,3],[4,-2,-3,1,1,2,3,7,3,5]])
print matrx
[[ 1 4 9 2 2 5 1 1 9 1]
[ 2 4 3 5 2 2 1 2 1 1]
[ 3 4 -2 -3 4 2 3 5 1 2]
[ 2 3 -3 -5 3 3 7 8 -4 1]
[ 3 4 2 3 4 2 3 7 3 2]
[ 1 4 9 3 4 3 3 2 9 4]
[ 2 1 3 5 2 2 3 2 3 3]
[ 3 6 8 3 7 2 3 5 3 2]
[ 5 -2 -3 5 2 3 7 8 4 3]
[ 4 -2 -3 1 1 2 3 7 3 5]]
And, let's suppose that the threshold is zero. Presently, I am finding the (2d) locations of the cells where the values are below zero using the following:
threshold = 0
mark_x = np.where( matrx<0 )[0]
mark_y = np.where( matrx<0 )[1]
Below, is a picture of the aforesaid matrix.
In my work, cells whose values are below the threshold mostly occur in blocks (as one can see in the matrix). At present, I am replacing all the cells where the values are below the threshold with the mean of the matrix (matrx
).
But, I would like do better and replace the values of elements which are below the threshold with the mean values of good neighboring elements adjoining the concerned cells. Here, "good" neighboring cells will be those neighboring cells whose values are above the threshold. I am a bit flexible with the selection of sizes of neighboring cells around cells which are below the threshold (the size of the neighboring cell will be the same for each cell which is below the threshold.)
The picture below gives a pictorial idea of what I want to achieve. In the picture given below, the red boundaries around each blob with values below the threshold, represent nearest neighbors. Inside each of these bounded boxes, cells with red tick marks are the ones whose average we will like to consider while replacing the values of the cells whose values are below the threshold.
When we find cells with values below the threshold, we are expecting to see blobs of unequal sizes; and also blobs which are near the boundary.
In Python, what is the best way to achieve this desired aim? I will very much appreciate any answer.
Upvotes: 5
Views: 2356
Reputation: 23556
This might work, however, you may prefer to keep the original matrix and make changes to a copy to make it more precise:
for x, y in zip(mark_x, mark_y) :
slice = matrx[max(0, x-2):x+2, max(0,y-2):y+2] # assuming you want 5x5 square
matrx[x,y] = np.mean([i for i in slice.flatten() if i > 0]) # threshold is 0
gives the result:
array([[1, 4, 9, 2, 2, 5, 1, 1, 9, 1],
[2, 4, 3, 5, 2, 2, 1, 2, 1, 1],
[3, 4, 3, 3, 4, 2, 3, 5, 1, 2],
[2, 3, 3, 3, 3, 3, 7, 8, 3, 1],
[3, 4, 2, 3, 4, 2, 3, 7, 3, 2],
[1, 4, 9, 3, 4, 3, 3, 2, 9, 4],
[2, 1, 3, 5, 2, 2, 3, 2, 3, 3],
[3, 6, 8, 3, 7, 2, 3, 5, 3, 2],
[5, 4, 3, 5, 2, 3, 7, 8, 4, 3],
[4, 4, 4, 1, 1, 2, 3, 7, 3, 5]])
Upvotes: 5