Mean a matrix columnwise based on another logical matrix

I want to mean the matrix a based on the logical matrix b columnwise: In other words this:
mean(a(b(:,1)))
mean(a(b(:,2)))
...
a =[
7 8 5 3
1 1 4 7
9 3 8 7
10 1 8 2
7 1 2 2
8 9 5 5
8 7 5 10
4 4 7 4
7 10 8 6
2 1 8 3];
b =logical([
0 0 1 0
1 0 1 0
1 0 1 1
1 0 1 1
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
1 0 0 1
0 0 0 1]);

1 Comment

This is obviously an interesting question, which allows to shed light on different powers of Matlab. +1

Sign in to comment.

 Accepted Answer

Or:
m = sum(a .* b, 1) ./ sum(b, 1);

4 Comments

I always appreciate the alternatives..
Me too. And this one is the leanest and fastest one :-)
I agree Jan, +1, silly of me not to think of simply using the b matrix to get the correct number of nonzero elements.

Sign in to comment.

More Answers (4)

b1 = bsxfun(@times,b,1:4);
out = accumarray(b1(b),a(b),[],@mean);
or
[~,jj] = find(b);
out = accumarray(jj,a(b),[],@mean);
and in line with accumarray:
out = accumarray(ceil(find(b)/size(b,1)),a(b),[],@mean);

2 Comments

I will celebrate the day that I will understand accumarray... Thank you Andrei
Although I do not think that accumarray is the fastest approach here, I vote for it a sign of my admiration for all successful accumarray masters.

Sign in to comment.

you mean just:
mean(a.*b)
or do you want the mean of just the nonzero entries? In other words, divide by the right number of elements.
C = a.*b;
for nn = 1:size(C,2)
numelements(nn) = nnz(C(:,nn));
end
colsumz = sum(C);
meanz = colsumz./numelements;
c=a.*b
c(c==0)=nan;
out=nanmean(c)

2 Comments

Just learned about nanmean. I've been looking for a function like that for quite some time. I've always used some workaround. Thanks!

Sign in to comment.

Products

Tags

Community Treasure Hunt

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

Start Hunting!