Replace NaN with mean of previous values

4 ビュー (過去 30 日間)
Tomás Nunes
Tomás Nunes 2018 年 5 月 10 日
編集済み: Jan 2018 年 5 月 12 日
Hello, I have a vector that contains some Nan's. How can I replace them with a mean of the previous 5 values? This is what I have tried until now:
for i = 254:1:size(vector)
vector(isnan(vector(i))) = mean(vector(i-5:i-1));
end
and
for i = 254:1:size(vector)
if vector(i) == NaN
vector(i) = mean(vector(i-5:i-1));
end
end
Thank you!
  4 件のコメント
Tomás Nunes
Tomás Nunes 2018 年 5 月 11 日
do you know what is wrong with the formula? Thank you
Jan
Jan 2018 年 5 月 12 日
If the 2nd one is wanted, Ameer Hamza's answer does not, what you want.

サインインしてコメントする。

採用された回答

Ameer Hamza
Ameer Hamza 2018 年 5 月 10 日
編集済み: Ameer Hamza 2018 年 5 月 10 日
You can avoid for loop altogether
ind = find(isnan(vector));
vector(ind) = arrayfun(@(x) nanmean(vector(x-5:x-1)), ind);
a vectorized code is usually faster and at worst equivalent to loops. Also using arrayfun() makes your code more readable.
  5 件のコメント
Tomás Nunes
Tomás Nunes 2018 年 5 月 11 日
i mean, this is kinda dumb, right? it would be easier to set the nans to a stupid value like 100000 (which has nothing to do with the remaining values of the vector) and then replace them with the mean of the previous days. it would be quite easier, correct?
Ameer Hamza
Ameer Hamza 2018 年 5 月 11 日
編集済み: Ameer Hamza 2018 年 5 月 11 日
Why do you need to set nan to 100000. You can directly replace them as I showed in my answer. Does your vector contain more the 5 consecutive nan, in that case, this method will not work. Also, an @Jan pointed out in the comment, if more then one nan occur closely (less than 5 elements apart) my answer do average using first example in Jan's comment.

サインインしてコメントする。

その他の回答 (3 件)

Steven Lord
Steven Lord 2018 年 5 月 10 日
Use the fillmissing function, specifically the F = fillmissing(A,movmethod,window) syntax. You're going to want to specify a two-element vector [b f] as the window input as described in the documentation for that input argument.

Fangjun Jiang
Fangjun Jiang 2018 年 5 月 10 日
Use the second code, replace size() with numel()

Jan
Jan 2018 年 5 月 11 日
編集済み: Jan 2018 年 5 月 12 日
You forgot to mention, which problem you have with the shown code.
1. size(vector) replies a vector. If vector is a row vector, the output is e.g. [1, 1000]. When this is used in
for i = 254:1:size(vector)
only the first element is used. So this is equivalent to:
for i = 254:1:1
As Fangjun Jiang has suggested already, use numel instead of size.
2. A comparison with NaN is FALSE in every case by definition. See:
NaN == NaN
Therefore
if vector(i) == NaN
must fail. Use this instead:
if isnan(vector(i))
A working version:
for k = 254:numel(vector)
if isnan(vector(k))
vector(k) = mean(vector(k-5:k-1));
end
end
Or
for k = find(isnan(vector))
vector(k) = mean(vector(k-5:k-1));
end

Community Treasure Hunt

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

Start Hunting!

Translated by