简体   繁体   中英

From the matrix M, how to find the cell of vectors Vi, indicating the index line of the value 2 in each column Ci?

From the matrix M, how to find the cell of vectors Vi, indicating the index line of the value 2 in each column Ci ?

Example:

M=[1 0 2 0;
   0 2 2 1;
   2 1 0 2;
   2 1 2 0;
   0 2 1 1]

The expected output: {[3 4],[2 5],[1 2 4],[3]}

You can use a combination of find in concert with accumarray :

[row,col] = find(M == 2);
out = accumarray(col, row, [size(M,2) 1], @(x) {x});

To double check:

>> celldisp(out)

out{1} =

     3
     4

out{2} =

     2
     5

out{3} =

     1
     2
     4

out{4} =

     3

You would use the column locations of where you found the number 2 as the binning parameter and the row locations of where the number 2 is found to group those locations together in the same bin. The default behaviour of accumarray is to sum values that belong to the same bin, but instead of summing values, we group everything together into a single array and the output would thus be a cell array where each index is the desired column location and the cell contents tell you which rows contained the number 2 for the corresponding column.

This should also correctly handle the case if there are no values of 2 in a column. The output for this particular column gives you the empty array. For example, if we had:

>> M = [1 0 2 0; 0 2 2 1; 2 1 0 1; 2 1 2 0; 0 0 1 1]

M =

     1     0     2     0
     0     2     2     1
     2     1     0     1
     2     1     2     0
     0     0     1     1

Running the code at the beginning of the post, we get:

>> celldisp(out)

out{1} =

     3
     4

out{2} =

     2

out{3} =

     1
     2
     4

out{4} =

     []

With arrayfun -

out = arrayfun(@(n) find(M(:,n)==2),1:size(M,2),'Uni',0)

Verify results with celldisp -

>> celldisp(out)
out{1} =
     3
     4
out{2} =
     2
     5
out{3} =
     1
     2
     4
out{4} =
     3

Yet another approach:

M = [1 0 2 0; 0 2 2 1; 2 1 0 2; 2 1 2 0; 0 2 1 1]; %// data
v = 2; %// sought value
X = bsxfun(@times, (1:size(M,1)).', M==v); %'
y = nonzeros(X);
z = sum(X~=0, 1);
result = mat2cell(y.', 1, z);

This returns [] for columns that don't contain the sought value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM