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

New to MATLAB?

Mean a matrix columnwise based on another logical matrix

Asked by Giorgos Papakonstantinou

Giorgos Papakonstantinou

on 16 Jun 2013
Accepted Answer by Jan Simon

Jan Simon

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

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

Giorgos Papakonstantinou

Tags

Products

5 Answers

Answer by Jan Simon

Jan Simon

on 16 Jun 2013
Accepted answer

Or:

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

4 Comments

Jan Simon

Jan Simon

on 17 Jun 2013

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

Wayne King

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.

Andrei Bobrov

Andrei Bobrov

on 18 Jun 2013

+1

Jan Simon

Jan Simon

Answer by Andrei Bobrov

Andrei Bobrov

on 17 Jun 2013
Edited by Andrei Bobrov

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

Giorgos Papakonstantinou

on 17 Jun 2013

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

Jan Simon

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

Andrei Bobrov

Answer by Wayne King

Wayne King

on 16 Jun 2013
Edited by Wayne King

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

Wayne King

Answer by Azzi Abdelmalek

Azzi Abdelmalek

on 16 Jun 2013
c=a.*b
c(c==0)=nan;
out=nanmean(c)

2 Comments

Giorgos Papakonstantinou

Giorgos Papakonstantinou

on 17 Jun 2013

Thank you! You had the shortest!

John Doe

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

Azzi Abdelmalek

Answer by Giorgos Papakonstantinou

Giorgos Papakonstantinou

on 17 Jun 2013

Thank you guys!

0 Comments

Giorgos Papakonstantinou

Giorgos Papakonstantinou

Contact us