0

In numpy, I can find which 2D array is the least of all 3 2D arrays as follows:

mat_a = np.random.random((5, 5))
mat_b = np.random.random((5, 5))
mat_c = np.random.random((5, 5))
bigmat = np.stack((mat_a, mat_b, mat_c)) # this is a 3, 5, 5 array
minima = np.argmin(bigmat, axis=0) # contains a 5x5 array of 0,1,2 for a,b,c respectively

How do I extend this, so that it works to find 2nd least of all 3 2D arrays?

-- EDIT:

Expected output is a 5 x 5 numpy array, where each element is represents which of the 3 arrays (mat_a, mat_b, mat_c) is the 2nd least value in bigmat.

So, structure will be same as minima, except minima can only show which array is least.

user308827
  • 21,227
  • 87
  • 254
  • 417
  • What's your expected output? – Mazdak Sep 06 '16 at 20:00
  • thanks @Kasramvd, updated question. Basically, I want same structure as `minima`. The only difference is that `minima` only shows the least value but in this case we want 2nd least value instead – user308827 Sep 06 '16 at 20:05
  • 1
    There is also a `partition/argpartition` that does not require a full sort. – hpaulj Sep 06 '16 at 20:10
  • @Kasramvd, so something like: `np.argsort(bigmat, axis=0)[1]` will give me middle element? – user308827 Sep 06 '16 at 20:16
  • I think so, but @hpaulj Is right you might consider using [argpartition](http://docs.scipy.org/doc/numpy/reference/generated/numpy.argpartition.html) rather than sorting the whole of array. – Mazdak Sep 06 '16 at 20:17
  • Read this question for more info http://stackoverflow.com/questions/10337533/a-fast-way-to-find-the-largest-n-elements-in-an-numpy-array – Mazdak Sep 06 '16 at 20:20

1 Answers1

0

I'll bet np.argsort() is the most efficient way.

FYI, here's an interesting thing you can do with array indexing that will also solve your problem (though less efficiently):

max_value = np.max(bigmat)
maskmat = np.array([minima == i for i in xrange(bigmat.shape[0])])
bigmat[maskmat] = max_value  # assign each minimum to the array-wide maximum
minima2 = np.argmin(bigmat, axis=0)
Luke Yeager
  • 1,400
  • 1
  • 17
  • 30