sum elements of matrix if...
2 views (last 30 days)
Show older comments
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.
Answers (2)
Matt Tearle
on 16 Oct 2012
Edited: Matt Tearle
on 16 Oct 2012
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 Comment
Matt Fig
on 16 Oct 2012
Edited: Matt Fig
on 16 Oct 2012
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!
See Also
Categories
Find more on Logical in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!