I have a 2 dimensional Numpy array that contains values. I need to find the index of biggest 100 values in a given slice of the array. The problem is, that the index of the values, must be relative to the whole image, not relative to the slice.
So, if my array is 255 x 255, and has random values ranging from 1 to 12000.
I need to know what are the 100 biggest values in the range [120:120,160:160]. But its coordinates/indexes must be relative to the whole array, not the slice.
for example
[1, 1, 1, 2]
[1, 1, 3, 2]
[9, 9, 9, 2]
[9, 9, 9, 2]
Lets say that in above example, my slice is the 4 central values. (1,3,9,9) and I want the index of the 3 biggest values in this slice. The result should be: [1:2, 2:1, 2:2] as these are the absolute indexes of the values 3,9,9 that are the 3 biggest of my slice.
I tried by extracting the slice, flattening it, and using argpartition, but that gave me the index relative to the slice, and not relative to the whole array.
This is what I tried:
depthRoi = depthFrame[top:bottom, left:right]
depthRoiFlat = depthRoi.flatten()
ind = np.argpartition(depthRoiFlat, -1000)[-1000:]
DepthFrame is the whole array. depthRoi is my slice of interest, and ind, is the extracted index of the 1000 biggest values of my slice. The index is relative to the ROI, not the whole array tough..
How can this be done?
Thank you
CodePudding user response:
To Find the first n max values in sub-block
a = np.random.rand(255,255) ## some random array
n_sort = 10 ## number of first n max values
block_start = [20,50] ## block starting corner
slice_arr = a[block_start[0]:100,block_start[1]:90] ## your slice
idx_slice = np.argpartition(slice_arr.reshape(-1), -n_sort)[-n_sort:] ## sort the slice
idx_req = np.zeros((n_sort,2),dtype=int) ## create a array to store indices
q_rem = np.divmod(idx_slice,slice_arr.shape[1]) ## for a A[m,n] array,
## contd. A[i,j] corresponds to i*n j element in flatten array. so you get i,j from quotient and reminder of flattened index when divided by n
## You can also use np.unravel_index
## q_rem = np.unravel_index(idx_slice,shape=slice_arr.shape)
idx_req[:,0] = block_start[0] q_rem[0]
idx_req[:,1] = block_start[1] q_rem[1]
CodePudding user response:
Variant using unravel_index
on the original OP code
top, bottom, left, right = 1, 3, 1, 3
N = 3
depthRoi = depthFrame[top:bottom, left:right]
depthRoiFlat = depthRoi.flatten()
ind = np.argpartition(depthRoiFlat, -N)[-N:]
out = np.c_[np.unravel_index(ind, (bottom-top, right-left))] [top, left]
output:
array([[1, 2],
[2, 1],
[2, 2]])
As lists of coordinates:
tuple(out.T)
output: (array([1, 2, 2]), array([2, 1, 2]))