sum elements of matrix if...
2 次查看(过去 30 天)
显示 更早的评论
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
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
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!
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Logical 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!