1

See the below example to understand my question better.

Suppose their are two arrays A and B:

A=array([[1,2,3,4],
         [5,6,7,8],
         [9,10,11,12]])

B=array([[3,4,12,2],
         [5,11,1,6],
         [9,10,7,8]])

In B find the coordinates of top 5 elements(12,11,10,9,8) in it.

expected output1:

coordinates=(0,2)
            (1,1)
            (2,1)
            (2,0)
            (2,3)

Now, I want to multiply elements whose positions are in coordinates (0,2),(1,1),(2,1),(2,0),(2,3) in A with 10.

Then the expected output2 will be:

[30,60,100,90,120]
mArk
  • 630
  • 8
  • 13
  • See https://stackoverflow.com/questions/6910641/how-do-i-get-indices-of-n-maximum-values-in-a-numpy-array, 2nd answer. – B. M. Apr 12 '19 at 05:46
  • Possible duplicate of [How do I get indices of N maximum values in a NumPy array?](https://stackoverflow.com/questions/6910641/how-do-i-get-indices-of-n-maximum-values-in-a-numpy-array) – B. M. Apr 12 '19 at 05:48
  • @B.M. in the links you have mentioned it returns the postion of max value elements which are in a single row. ie in a 1 dimensional array. where as here i'll be dealing with a 2dimensional array(in practical situations I will work with 25*38 and more shape arrays) and I want the indices/coordinates of max values in this 2d array. please note `np.unravel_index(B.argmax(), B.shape)` This command helps me to get the coordinate of only top 1 max value in an array but I don't know how to get the coordinates of top 5 max value's coordinates using this command . – mArk Apr 12 '19 at 06:59

3 Answers3

1

Using numpy.array.ravel with numpy.array.argsort:

A.ravel()[B.ravel().argsort()[-5:][::-1]] * 10

Output:

array([ 30,  60, 100,  90, 120])
Chris
  • 29,127
  • 3
  • 28
  • 51
  • Thank you for your quick response. Suppose A is a grey scale Image and each element in A denotes a segment with 2dimensions. I have to apply "threshold_otsu" to the elements whose coordinates I got from B instead of multiplying them with 10. Then how should I change the code? Code to apply threshold_otsu to whole image is : >> from skimage.filters import threshold_otsu >>thresh = threshold_otsu(A,16) Note-Here I assumed A to be a grey scale image and each element in it to be a segment with 2 dimensions. – mArk Apr 12 '19 at 05:23
  • Instead of multiplying 10, try `threshold_otsu(A.ravel()[B.ravel().argsort()[-5:][::-1]], 16)`? – Chris Apr 12 '19 at 06:19
1

For big arrays, argpartiton will be more efficient :

A=np.random.rand(100,100)
B=np.random.rand(100,100)

%timeit A.ravel()[np.argpartition(B,B.size-5,None)[-5:]] * 10
459 µs ± 37.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit A.ravel()[B.ravel().argsort()[-5:][::-1]] * 10
2.85 ms ± 34.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
B. M.
  • 18,243
  • 2
  • 35
  • 54
1

code to get the expected output 1 :

C=(B.ravel().argsort()[-5:][::-1])
cord=(np.unravel_index(C, B.shape))

Output :

(array([0, 1, 2, 2, 2], dtype=int64), array([2, 1, 1, 0, 3], dtype=int64))

## here 1st array gives the row coordinates and 2nd array gives the column coordinates of top 5 elements in B. In order.
mArk
  • 630
  • 8
  • 13