Hi MATLAB community,
I wrote a code for identify 999999 to substitute to NaN, my purpose is replace NaN to mean of column data,
I tried follow code:
[l,c]=size(matrix) % size (324,25)
for w=1:c
for q = 1:l
if matrix(q,w)==999999
matrix(q,w) =NaN;
matrix(isnan(matrix))= mean(matrix(:,w),'omitnan'); % in the case NaN is present in column 21, it will substitute the element for mean of all element in column 21
end
end
end
Could help me?
Grateful

1 Comment

Omitnan did not exist in your release. One of the toolboxes had nanmean()

Sign in to comment.

 Accepted Answer

Adam Danz
Adam Danz on 5 Jun 2019
Edited: Adam Danz on 10 Jun 2019
Check out nanmean() in the stats & machine learning toolbox.
An alternative that doesn't require any toolboxes:
nanidx = isnan(matrix(:,w));
mean(matrix(~nanidx,w)
Update following comments below
To compute the mean of each column of a matrix while ignoring a key value (999999),
% Create fake data
key = 999999;
matrix = magic(10);
matrix(randi(100,1,10)) = key;
% Identify the columns that contain at least one 999999
isKey = matrix == key;
colIdx = any(isKey,1);
% Count the number of rows per column that are not 999999
rowCount = sum(~isKey);
% Temporarily replace 999999 with 0 and calculate the column means
matrixTemp = matrix .* ~isKey;
colMean = sum(matrixTemp)./rowCount;
% The 2nd block above can be reduced to
% isKey = matrix == key;
% colMean = sum(matrix .* ~isKey)./ sum(~isKey);

14 Comments

Thank you very much Adam, for help,
It's correct how I inserted?
for w=1:c
for q = 1:l
if matrix(q,w)==999999
matrix(q,w) =NaN;
nanidx = isnan(matrix(:,w));
mean(matrix(~nanidx,w))
end
end
end
Grateful
You are not saving the result.
Adam Danz
Adam Danz on 5 Jun 2019
Edited: Adam Danz on 5 Jun 2019
It looks correct (I edited your comment and formatted your code with correct indentation but I didn't make any other changes). However, there are some other issues.
1) you're not storing the value of this function anywhere: mean(matrix(~nanidx,w))
2)If you're trying to replace all values of 999999 with NaN, you can do that more efficiently outside of the loop with this: matrix(matrix==999999) = NaN
3) Is this really what you want to do? You want to take the mean of column 'w' only if matrix(q,w) is 999999? That doesn't seem right.
The third option Adam,
I would to like replace the (999999) to mean of column (w);
Grateful
Adam Danz
Adam Danz on 5 Jun 2019
Edited: Adam Danz on 5 Jun 2019
If you want the mean of each column, ignoring 999999 and NaN values, this is one way you can do that:
matrix(matrix==999999) = NaN;
nonNanCount = sum(~isnan(matrix),1); %number of non-NaN per column
matrixTemp = matrix; %Temporarily replace matrix
matrixTemp(isnan(matrixTemp)) = 0; %Replace NaN with 0
colMean = sum(matrixTemp,1)./nonNanCount; %mean of each column, ignoringNaN
Adam Danz
Adam Danz on 5 Jun 2019
Edited: Adam Danz on 5 Jun 2019
If you want the mean of each column only if there is a 999999 within the column and ignore that value, this is one way to do that:
% PRIOR to to the 5 lines in my comment above,
colIdx = any(matrix==999999,1); % Which columns have 999999
% Then do the 5 lines in the comment above
% Then pull out the means from columns with 999999
colMean(colIdx)
Adam, thank you very much for help,
I need to replace the value where there is (999999) for a mean of
respective column,
I believe that is a little modification on code.
Grateful
No problem; One of my comments above does that. It takes the mean of each column and ignores any 999999 values.
Hi Adam,
I tried the solution above, but it show the follow error:
Undefined function 'colMean' for input arguments of type 'logical'.
Error in depuracao_versao_2012 (line 13)
colMean(colIdx)
Could help me?
Grateful
I've updated my answer to show a full working example with fake data.
Perfectly Adam,
Works,
But I need a help more,
How I can replace each value of colMean in the respectly column?
For example, I tried the code:
matrixTemp = matriz_media .* ~isKey;
colMean = sum(matrixTemp)./rowCount;
colMean=transpose(colMean);
matrixTemp(matrixTemp==0)=colMean(1)
This code replace all zero in matrix with the mean of position 1 (colMean(n,1)),but I need the mean of column 4 replace zero in column 4, mean of column 9 replace zero in column 9 like that respectly, I could use for looping?
I tried the follow code:
for i=1:c
for j=1:l
if matrixTemp(j,i)== 0
matrixTemp(j,i)== colMean(i,1);
end
end
end
But not works
Could help me?
Very Grateful your patience.
Guilherme
Adam Danz
Adam Danz on 10 Jun 2019
Edited: Adam Danz on 10 Jun 2019
Happy to help.
To address your new question, try this out
[rowIdx,colIdx] = find(matrixTemp==0);
matrixTemp(sub2ind(size(matrixTemp),rowIdx,colIdx)) = colMean(colIdx);
Thank so much Adam,
I don't have words to show my thanks,
I am very grateful,
Guilherme
I've been there; glad I could help!

Sign in to comment.

More Answers (0)

Categories

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!