Indexing a Matrix Using a Predefined Rule

I have a 72x3 double that looks like

1 1 24 1 1 125 2 3 17 6 2 54 5 1 110 4 4 55 6 2 200 1 4 16 3 3 87 ... 6 2 63 

I would like to find the value from column 3 based on a combination of the values ​​from columns 1 and 2. For example, let me call any value from column 1 m , the value from column 2 n and the corresponding value from column 3 p . If m = 2 , n = 3 , this will correspond to line 3 and therefore p will be 17 . If m = 5 , n = 1 , this will give us line 5 and, therefore, b will be 110 . Note that there will be times when a set of m and n will give us two or more lines. An example would be m = 1 and n1 = 1 , which should give 24 from the first row and 125 from the second row. In this case, the output should be [24 125] . Similarly, a combination of m = 6 and n = 2 will give [54,200 63] . m varies from 1 to 6, and n - from 1 to 4. Any combination of m and n will give no more than 4 outputs. Can someone help me with this indexing issue?

Thank you very much.

Alex

+5
source share
3 answers

One approach assumes that A will be an input array N x 3 -

 %// Find unique rows using the first two columns of A [unqA12,~,idx] = unique(A(:,1:2),'rows') %// Group elements from 3rd column of A based on the indexing pairs from %// first coloumns of A and have these as a cell array A3vals = accumarray(idx,A(:,3),[],@(x) {x}) %// Horizontally concatenate these results to present the final output out = [num2cell(unqA12) A3vals] 

An example run at this input gives an output like -

 out = [1] [1] [2x1 double] [1] [4] [ 16] [2] [3] [ 17] [3] [3] [ 87] [4] [4] [ 55] [5] [1] [ 110] [6] [2] [3x1 double] 

Or using arrayfun -

 %// Find unique rows using the first two columns of A [unqA12,~,idx] = unique(A(:,1:2),'rows') %// Use arrayfun to do the groupings instead of accumarray this time out = [num2cell(unqA12) arrayfun(@(n) A(idx==n,3),1:max(idx),'Uni',0).'] 

Note that the order of the elements of the third column will not be preserved in the first approach, but the second approach will do this.

+4
source

This is not the fastest way, but a different approach for beginners like me :)

 in = [1 1 24; 1 1 125; 2 3 17; 6 2 54; 5 1 110; 4 4 55; 6 2 200; 1 4 16; 3 3 87]; m = input('Enter m '); n = input('Enter n '); Idx = all((cat(2,in(:,1) == m, in(:,2) == n)),2); out = in(:,3); out1 = out(Idx); 

Results:

 Enter m 6 Enter n 2 ans = 54 200 ---------------- Enter m 2 Enter n 3 ans = 17 
+3
source

If you only need the result for a given combination of m and n , you can only use indexing:

 m = 6; n = 2; result = x(x(:,1)==m & x(:,2)==n, 3).'; 
+1
source

All Articles