简体   繁体   中英

How to find one value from a matrix

0I have on matrix-

A=[1 2 2 3 5 5;
   1 5 5 8 8 7;
   2 9 9 3 3 5];

From matrix i need to count now many nonzero elements ,how any 1,how many 2 and how many 3 in each row of given matrix"A".For these i have written one code like:

    [Ar Ac]=size(A);

    for j=1:Ar 
        for k=1:Ac
            count(:,j)=nnz(A(j,:));
            d(:,j)=sum(A(j,:)== 1); 
            e(:,j)=sum(A(j,:)==2);  
            f(:,j)=sum(A(j,:)==3);          
    end
end

but i need to write these using on loop ie here i manually use sum(A(j,:)== 1),sum(A(j,:)== 2) and sum(A(j,:)== 3) but is there any option where i can only write sum(A(j,:)== 1:3) and store all the values in the different row ie, the result will be like-

b=[1 2 1;
   1 0 0;
   0 1 2];

Matlab experts need your valuable suggestions

Sounds like you're looking for a histogram count:

U = unique(A);
counts = histc(A', U)';
b = counts(:, ismember(U, [1 2 3]));

Example

%// Input matrix and vector of values to count
A = [1 2 2 3 5 5; 1 5 5 8 8 7; 2 9 9 3 3 5];
vals = [1 2 3];

%// Count values
U = unique(A);
counts = histc(A', U)';
b = counts(:, ismember(U, vals));

The result is:

b =
   1   2   1
   1   0   0
   0   1   2

Generalizing the sought values, as required by asker:

values = [ 1 2 3 ]; % or whichever values are sought
B = squeeze(sum(bsxfun(@(x,y) sum(x==y,2), A, shiftdim(values,-1)),2));

Here is a simple and general way. Just change n to however high you want to count. n=max(A(:)) is probably a good general value.

 result = [];
   n = 3;
   for col= 1:n
       result = [result, sum(A==col, 2)];
   end
   result

eg for n = 10

result =

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

Why not use this?

B=[];
for x=1:size(A,1)
B=[B;sum(A(x,:)==1),sum(A(x,:)==2),sum(A(x,:)==3)];
end

I'd do this way:

B = [arrayfun(@(i) find(A(i,:) == 1) , 1:3 , 'UniformOutput', false)',arrayfun(@(i) find(A(i,:) == 2) , 1:3 , 'UniformOutput', false)',arrayfun(@(i) find(A(i,:) == 3) , 1:3 , 'UniformOutput', false)'];

res = cellfun(@numel, B);

Here is a compact one:

sum(bsxfun(@eq, permute(A, [1 3 2]), 1:3),3)

You can replace 1:3 with any array. you can make an anonymous function for it

rowcnt = @(M, R) sum(bsxfun(@eq, permute(M, [1 3 2]), R),3);

then running it on your data returns

>> rowcnt(A,1:3)

ans =

     1     2     1
     1     0     0
     0     1     2

and for more generalized case

>> rowcnt(A,[1 2 5 8])

ans =

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

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