Reputation: 1804
I'm trying to figure out the best way of doing this, ideally in Octave, but I'll take NumPy at a pinch.
Let's say I have an axb matrix M. If I want the row indices of the maximum value in any given column, [x, xi] = max(M)
will return these indices for me as a row vector.
For example, if M is:
1 3 5
2 9 1
7 2 4
The above will return row vector [3 2 1]
as xi
; A vector of the indices of each row which contains the maximum value for that column. This is good. I want this row vector.
But what if I want the top n such row vectors?
[edited to explain this better]
For the above example, the first such vector would be the above [3, 2, 1]
, (the indices of the rows with the highest values for each given column). The second such vector would be [2 1 3]
, (the indices of the rows with the second-highest values for each column).
I could do it iteratively, but my actual matrices have many thousands of rows, so this would be quite computationally expensive. I can't find any obvious matrix utility function to help me achieve this. Any suggestions?
Upvotes: 4
Views: 6419
Reputation: 2978
Here's how to do it in numpy. Please take a look at numpy.argmax
, which returns indices of the maximum values along an axis. Note that this indices are 0-based so you may want to add/subtract 1 to it to make it 1-based as in matlab.
Taking the same example of @Stewie Griffin :-)
In [3]: a = np.array([[16,2,3,13], [5,11,10,8], [9,7,6,12], [4,14,15,1]])
In [4]: N = 2 # A 0-based index
In [5]: np.argmax(a[N], axis=0)
Out[5]: array([0, 1, 1, 0])
Here the axis is 0 because you want max indices in each column. Change it to 1 if you want max indices in each raw. Also, there is numpy.argmin
if you want min.
Based on your clarification,you want nth largest indices in each column, which is very easy with numpy.argsort
.
In [11]: A = np.argsort(a, axis=0) # returns indices of smallest to largest values in each column
In [12]: A
Out[12]:
array([[3, 0, 0, 3],
[1, 2, 2, 1],
[2, 1, 1, 2],
[0, 3, 3, 0]])
In [13]: N = 1 # 0-based index
In [14]: A[N] # 2nd smallest indices
Out[14]: array([1, 2, 2, 1])
In [14]: A[-N-1] # 2nd largest indices
Out[14]: array([2, 1, 1, 2])
Upvotes: 2
Reputation: 14939
Like this?
% N is the number of rows you want to include.
[x, xi] = max(a(1:N,:))
This gives you:
a =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
N = 3;
[x, xi] = max(a(1:N,:))
x =
16 11 10 13
xi =
1 2 2 1
Upvotes: 2
Reputation: 526
I assume that you mean you want the n biggest values from the matrix. In which case, Get the indices of the n largest elements in a matrix is almost the same question as this, except there the OP wanted the largest values of the whole matrix, not individual maximums. This should get you what you need
n = 2; % The depth to get
M = [ 1, 3, 5; ...
2, 9, 1; ...
7, 2, 4 ]; % The matrix to look at
[m, mi] = sort(M, 'descend'); % Sort the to access them
x = m(1:n, :) % Get the values
xi = mi(1:n, :) % and the indices
Upvotes: 5