Замените NaN последним значением, отличным от NaN

У меня есть матрица с несколькими значениями NaN, и я хочу заменить их последним значением, отличным от NaN. Матрица очень большая, поэтому в идеале я бы сделал ее векторизованной.

Вот минимальный рабочий пример:

M = [
NaN NaN NaN 3
7   NaN NaN 1
NaN NaN NaN 9
NaN 6   NaN NaN
NaN NaN NaN NaN
8   NaN NaN 8
NaN 5   NaN NaN
NaN NaN NaN NaN
9   NaN NaN NaN]

И вывод должен быть:

Out = [
NaN NaN NaN 3
7   NaN NaN 1
7   NaN NaN 9
7   6   NaN 9
7   6   NaN 9
8   6   NaN 8
8   5   NaN 8
8   5   NaN 8
9   5   NaN 8]

Мне было интересно, сталкивался ли кто-нибудь с подобной проблемой и знает ли эффективный способ ее решения. Я прочитал этот аналогичный пост, но все решения кажутся чтобы включить цикл for.


person phdstudent    schedule 22.03.2017    source источник
comment
Почему вы заменяете только одни NaN, а не другие? Это за колонку? За строку? За что-то другое?   -  person excaza    schedule 22.03.2017
comment
Извиняюсь. Это была опечатка. Я исправил это. Это на столбец.   -  person phdstudent    schedule 22.03.2017
comment
Я сомневаюсь, что это возможно, я не думаю, что NAN, вероятно, обрабатывается векторизованными функциями stackoverflow.com/questions/15560567/   -  person Antonio    schedule 22.03.2017
comment
Ну, NaN можно заменить любым произвольным числом, например -99.   -  person phdstudent    schedule 22.03.2017
comment
Я все еще не понимаю столбцы 1 и 2 желаемого результата.   -  person excaza    schedule 22.03.2017
comment
@excaza он заменяет все NaN после первого ввода, отличного от nan, на первый ввод, не относящийся к nan, а после 2-го ввода, отличного от nan, он заменяет все nan вторым вводом, не относящимся к nan, и так далее. и он делает это по столбцам.   -  person Max    schedule 22.03.2017
comment
Первый столбец начинается с NaN. Это держится как есть. Потом идет семерка. Все последующие значения NaN заменяются на семь. Пока не получишь восьмерку. Все последующие NaN заменяются на NaN. Пока не получите 9.   -  person phdstudent    schedule 22.03.2017
comment
Попробуйте методы inpainting, которые заполняют недостающие данные соседями. Вот функция обмена файлами: mathworks.com/matlabcentral/fileexchange/4551-inpaint- нанс   -  person Ozcan    schedule 22.03.2017
comment
Имеют ли значения известный диапазон? Например, разрешены только значения 0-9 или они могут быть любыми?   -  person Abhinav    schedule 22.03.2017
comment
Они должны быть больше нуля. Если отрицательные, они точно -0,01. Так что в рамках этих критериев они могут быть какими угодно.   -  person phdstudent    schedule 22.03.2017


Ответы (2)


Вот один векторный подход -

mask = ~isnan(M);
cumsums = cumsum(mask,1);
invalid_mask = cumsums==0;
cumsums(invalid_mask) = 1;

shifts = [0 cumsum(sum(mask(:,1:end-1),1))];

idx = bsxfun(@plus,cumsums, shifts);
nums = M(mask);
out = nums(idx);
out(invalid_mask)=nan;
person Divakar    schedule 22.03.2017
comment
Впечатляющий! Спасибо! - person phdstudent; 22.03.2017

Ознакомьтесь с функцией fillmissing, если у вас версия R2016b или выше. Вы можете использовать метод 'previous', чтобы сделать именно это.

person CKT    schedule 22.03.2017