## Mean a matrix columnwise based on another logical matrix

Asked by Giorgos Papakonstantinou

### Giorgos Papakonstantinou (view profile)

on 16 Jun 2013
Accepted Answer by Jan Simon

### Jan Simon (view profile)

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]);```

Jan Simon

### Jan Simon (view profile)

on 18 Jun 2013

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

## Products

### Jan Simon (view profile)

Answer by Jan Simon

### Jan Simon (view profile)

on 16 Jun 2013

Or:

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

Jan Simon

### Jan Simon (view profile)

on 17 Jun 2013

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

Wayne King

### Wayne King (view profile)

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

on 18 Jun 2013

+1

### Andrei Bobrov (view profile)

Answer by Andrei Bobrov

### Andrei Bobrov (view profile)

on 17 Jun 2013
Edited by Andrei Bobrov

### Andrei Bobrov (view profile)

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);
```

Giorgos Papakonstantinou

### Giorgos Papakonstantinou (view profile)

on 17 Jun 2013

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

Jan Simon

### Jan Simon (view profile)

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.

### Wayne King (view profile)

Answer by Wayne King

### Wayne King (view profile)

on 16 Jun 2013
Edited by Wayne King

### Wayne King (view profile)

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;```

### Azzi Abdelmalek (view profile)

Answer by Azzi Abdelmalek

### Azzi Abdelmalek (view profile)

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

Giorgos Papakonstantinou

### Giorgos Papakonstantinou (view profile)

on 17 Jun 2013

Thank you! You had the shortest!

John Doe

### John Doe (view profile)

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!

### Giorgos Papakonstantinou (view profile)

Answer by Giorgos Papakonstantinou

### Giorgos Papakonstantinou (view profile)

on 17 Jun 2013

Thank you guys!

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