MATLAB: заменить ведущие нули каждого столбца на NaN - PullRequest
0 голосов
/ 05 сентября 2018

У меня есть 3D-матрица под названием mat. Каждый столбец может содержать или не содержать переменное число ведущих нулей. Мне нужно заменить их NaNs. Важно понимать, что после появления первых ненулевых элементов в любом столбце может следовать еще больше нулей. То есть простое индексирование ВСЕХ нулей в матрице и замена их на NaN не приведет к правильному результату.

У меня есть рабочее решение. Тем не менее, он содержит два цикла for. Мне интересно, можно ли векторизовать и избавиться от петли. В действительности, mat может быть очень большим, что-то вроде 10000x15x10000. Поэтому я довольно чувствителен к скорости выполнения.

Вот мой игрушечный пример:

% Create test matrix
mat = randi(100,20,5,2);
mat(1:5,1,1) = 0;
mat(1:7,2,1) = 0;
mat(1:3,4,1) = 0;
mat(1:10,5,1) = 0;
mat(1:2,1,2) = 0;
mat(1:3,3,2) = 0;
mat(1:7,4,2) = 0;
mat(1:4,5,2) = 0;

% Find first non-zero element in every column
[~, firstNonZero] = max( mat ~= 0 );

% Replace leading zeros with NaN
% How to vectorize this part???
[nRows, nCols, nPlanes] = size(mat);
for j = 1 : nPlanes

   for i = 1 : nCols

       mat(1:firstNonZero(1, i, j)-1, i, j) = NaN;

   end

end

1 Ответ

0 голосов
/ 05 сентября 2018

Вы можете использовать cumsum для создания кумулятивной суммы по каждому столбцу, тогда все начальные нули имеют кумулятивную сумму, равную нулю, в то время как все промежуточные нули имеют кумулятивную сумму больше нуля ...

mat( cumsum(mat,1) == 0 ) = NaN;

Как предлагается в комментариях, если ваш mat имеет отрицательные значения, есть вероятность, что кумулятивная сумма будет 0 позже ... используйте вместо этого сумму абсолютных значений

mat( cumsum(abs(mat),1) == 0 ) = NaN;

Обратите внимание, что по умолчанию cumsum работает по первому не-одиночному измерению, вы можете использовать необязательный аргумент dim, чтобы указать измерение. Я использовал dim=1 для принудительного выполнения операции по столбцам, если ваш mat может иметь высоту 1, но это значение по умолчанию для любой матрицы с высотой больше 1.

Обратите внимание, что для сравнения используется ==, вы можете прочитать Почему 24,0000 не равно 24,0000 в MATLAB? и использовать пороговое значение для сравнения на равенство.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...