sum elements of matrix if...

2 次查看(过去 30 天)
Sargondjani
Sargondjani 2012-10-16
Hi,
lets say i have two matrices:
A=rand(5,10);
B=[ones(1,10);3*ones(1,10);ones(1,10);ones(1,10);3*ones(1,10)];
I know what to get a matrix C has 3 rows, and each row corresponds to the indexes in B. Each column in C should have the mean of the elements in A where the index in B == row number of C.
Now I do it like this, but i want to eliminate the step with D:
C=NaN(3,10);
for ii = 1:3;
D=NaN(size(A));
D(B==i)=A(B==i);
C(ii,:) = nanmean(D);
end
... the faster the better :-) thanks in advance!
The problem seems to be that A(B==ii) gives a column vector, while i want it to have the same size as A.

回答(2 个)

Matt Tearle
Matt Tearle 2012-10-16
编辑:Matt Tearle 2012-10-16
As far as I can figure out what you're doing, this is equivalent:
CRows = max(B(:));
C=NaN(CRows,10);
for i = 1:CRows;
C(i,:) = mean(A(all(B==i,2),:));
end
But it seems redundant to have a whole matrix of indices. Can you just do
C(i,:) = mean(A(B(:,1)==i,:));
or do you have to worry about the rows of B in some way?
EDIT TO ADD: BTW, if you have Statistics Toolbox, this will also work:
C = grpstats(A,B(:,1))
or
C = grpstats(A,nominal(B(:,1),[],1:CRows))
The latter keeps the row of NaNs (for indices that don't appear in B).
  1 个评论
Matt Fig
Matt Fig 2012-10-16
编辑:Matt Fig 2012-10-16
Sargondjani comments:
Ok, i was not clear let me try again. Actually, there is one more step, and I would like to do all without any for loop if possible...
VALUE = rand(6,10);
INDEX = round(3*rand(5,1)); %random indices between 0 and 3
INDEX(INDEX==0) = NaN;
For each column in VALUE i want the mean of the points with the same INDEX. This will be stored in a 3 by 10 matrix 'AVG_ind'. I can do this with a loop:
for ii = 1:3; TMP=NaN(size(VALUE)); for it = 1:10; VALUE(INDEX(:,it)==ii,it) TMP(INDEX(:,it)==ii,it)=VALUE(INDEX(:,it)==ii,it); end AVG_ind(ii,:) = nanmean(TMP,1); end
Is it possible to get rid of both loops? Or at least one?
Next I want to calculate the deviation of each point in VALUE compared the AVG_ind (with the corresponding index):
for ii = 1:3; for it = 1:10; DEV(INDEX(:,it)==ii,it) = VALUE(INDEX(:,it)==ii,it) / AVG_ind(ii,it); end end
And again, i hope this can also be done without any loops... Or at least I am pretty sure there is a fast way to calculate all the results much faster than what i do.
Again, many thanks for the help!

请先登录,再进行评论。


Sargondjani
Sargondjani 2012-10-17
It seems i can not edit my comment... so here again (sorry for mess, but i forgot to 'code' my code)
Ok, i was not clear let me try again. Actually, there is one more step, and I would like to do all without any for loop if possible...
VALUE = rand(6,10);
INDEX = round(3*rand(5,1)); %random indices between 0 and 3
INDEX(INDEX==0) = NaN;
For each column in VALUE i want the mean of the points with the same INDEX. This will be stored in a 3 by 10 matrix 'AVG_ind'. I can do this with a loop:
for ii = 1:3; TMP=NaN(size(VALUE)); for it = 1:10; VALUE(INDEX(:,it)==ii,it) TMP(INDEX(:,it)==ii,it)=VALUE(INDEX(:,it)==ii,it); end AVG_ind(ii,:) = nanmean(TMP,1); end
Is it possible to get rid of both loops? Or at least one?
Next I want to calculate the deviation of each point in VALUE compared the AVG_ind (with the corresponding index):
for ii = 1:3;
for it = 1:10;
DEV(INDEX(:,it)==ii,it) = ... VALUE(INDEX(:,it)==ii,it)/AVG_ind(ii,it);
end
end
And again, i hope this can also be done without any loops... Or at least I am pretty sure there is a fast way to calculate all the results much faster than what i do.
Again, many thanks for the help!

类别

Help CenterFile Exchange 中查找有关 Logical 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by