MATLAB Answers

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

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.


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

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.


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


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

  2 Comments

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!


Answer by Giorgos Papakonstantinou on 17 Jun 2013

Thank you guys!

  0 Comments


Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply today