Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

To resolve issues starting MATLAB on Mac OS X 10.10 (Yosemite) visit: http://www.mathworks.com/matlabcentral/answers/159016

Mean a matrix columnwise based on another logical matrix

Asked by Giorgos Papakonstantinou on 16 Jun 2013

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

Jan Simon on 18 Jun 2013

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

Giorgos Papakonstantinou

Tags

Products

5 Answers

Answer by Jan Simon on 16 Jun 2013
Accepted answer

Or:

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

4 Comments

Jan Simon on 17 Jun 2013

Me too. And this one is the leanest and fastest one :-)

Wayne King on 17 Jun 2013

I agree Jan, +1, silly of me not to think of simply using the b matrix to get the correct number of nonzero elements.

Jan Simon
Answer by Andrei Bobrov on 17 Jun 2013
Edited by Andrei Bobrov on 18 Jun 2013
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

Giorgos Papakonstantinou on 17 Jun 2013

I will celebrate the day that I will understand accumarray... Thank you Andrei

Jan Simon on 18 Jun 2013

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.

Andrei Bobrov
Answer by Wayne King on 16 Jun 2013
Edited by Wayne King on 16 Jun 2013

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;

0 Comments

Wayne King
Answer by Azzi Abdelmalek on 16 Jun 2013
c=a.*b
c(c==0)=nan;
out=nanmean(c)

2 Comments

Giorgos Papakonstantinou on 17 Jun 2013

Thank you! You had the shortest!

John Doe on 18 Jun 2013

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

Azzi Abdelmalek
Answer by Giorgos Papakonstantinou on 17 Jun 2013

Thank you guys!

0 Comments

Giorgos Papakonstantinou

Contact us