HarryL0
HarryL0

Reputation: 37

Mean and Standard Deviation of a column, ignoring zero values - Matlab

I am trying to find the mean of a column however I am having trouble getting an output for a function I created. My code is below, I cannot see what mistake I have made.

for j=1:48;
    C_f2 = V(V(:,3) == j,:);
    C_f2(C_f2==0)=NaN;
    m=mean(C_f2(:,4));
    s=std(C_f2(:,4));
    row=[j,m,s];
    s1=[s1;row];    
end

I have checked the matrix, C_f2 and that is full of values so should not be returning NaN. However my output for the matrix s1 is

1  NaN NaN
2  NaN NaN
3  NaN NaN
.  ... ...
48 NaN NaN

Can anyone see my issue? Help would me much appreciated!

The matrix C_f2 looks like,

1 185 01 5003
1 185 02 5009
. ... .. ....
1 259 48 5001

Upvotes: 1

Views: 3840

Answers (4)

Luis Mendo
Luis Mendo

Reputation: 112679

To compute the mean and standard deviation of each column excluding zeros:

A = [1 2;
     3 0;
     4 5;
     6 7;
     0 0]; %// example data
den = sum(A~=0); %// number of nonzero values in each column
mean_nz = bsxfun(@rdivide, sum(A), den);
mean2_nz = bsxfun(@rdivide, sum(A.^2), den);
std_nz = sqrt(bsxfun(@times, mean2_nz-mean_nz.^2, den./(den-1)));

The results for the example are

mean_nz =
    3.5000    4.6667

std_nz =
    2.0817    2.5166

The above uses the "corrected" definition of standard deviation (which divides by n-1, where n is the number of values). If you want the "uncorrected" version (i.e. divide by n):

std_nz = sqrt(mean2_nz-mean_nz.^2);

Upvotes: 0

hbaderts
hbaderts

Reputation: 14316

On line 3 you set all values which are zero to NaN. The mean function will return NaN as mean if any element is NaN. If you want to ignore the NaN values, you have to use the nanmean function, which comes with the Statistics toolbox. See the following example:

a = [1 NaN 2 3];

mean(a)
ans = 
    NaN

nanmean(a)
ans = 
    2

If you don't have the Statistics toolbox, you can exclude NaN elements with logical indexing

mean(a(~isnan(a)))
ans = 
    2

or it is possibly the easiest, if you directly exlude all elements which are zero instead of replacing them by NaN.

mean(a(a~=0))

Upvotes: 1

GameOfThrows
GameOfThrows

Reputation: 4510

Don't set it to NaN, any NaN involved computation without additional rules will return NaN,

use find to correctly index the none zero part of your column

say column n is your input

N = n(find(n~=0))

now do your Mu calculation

Upvotes: 0

chipaudette
chipaudette

Reputation: 1675

Your line C_f2(C_f2==0)=NaN; will put NaNs into C_f2. Then, your mean and std operations will see those NaNs and output NaNs themselves.

To have the mean and std ignore NaN, you need to use the alternate version nanmean and nanstd.

These are part of a toolbox, however, so you might not have them if you just have the base Matlab installation.

Upvotes: 0

Related Questions