Подтвердить что ты не робот

Как удалить нулевые компоненты в векторе в Matlab?

У меня есть вектор, например

a = [0 1 0 3]

Я хочу превратить a в b, который равен b = [1 3].

Как это сделать вообще? Итак, у меня есть вектор с некоторыми нулевыми компонентами, и я хочу удалить нули и оставить только ненулевые числа?

4b9b3361

Ответ 1

Если вы просто хотите удалить нули, оставив ненулевые нули в a, тогда самое лучшее решение -

a(a==0) = [];

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

a(find(a==0)) = [];

И когда вы устанавливаете некоторые элементы массива в [] в MATLAB, соглашение должно их удалить.

Если вы хотите поместить нули в новый результат b, оставив неизменным, лучший способ, вероятно,

b = a(a ~= 0);

Опять же, здесь используется логическое индексирование. Вы могли бы использовать эквивалентную версию (в терминах результата)

b = a(find(a ~= 0));

но mlint в конечном итоге помещает строку как ту, где чисто логический индекс был более эффективным и, следовательно, более уместным.

Как всегда, будьте осторожны с ТОЧНЫМИ испытаниями для нуля или для любого числа, если бы вы приняли элементы a, которые были в пределах некоторого эпсилонского толерантности к нулю. Проводят ли эти тесты как

b = a(abs(a) >= tol);

Это сохраняет только те элементы из a, которые по крайней мере такие же, как ваш допуск.

Ответ 2

Я только что наткнулся на эту проблему и хотел найти что-то о производительности, но не смог, поэтому сам написал тест script:

% Config:
rows = 1e6;
runs = 50;

% Start:
orig = round(rand(rows, 1));

t1 = 0;
for i = 1:runs
    A = orig;
    tic
    A(A == 0) = [];
    t1 = t1 + toc;
end
t1 = t1 / runs;

t2 = 0;
for i = 1:runs
    A = orig;
    tic
    A = A(A ~= 0);
    t2 = t2 + toc;
end
t2 = t2 / runs;

t1
t2
t1 / t2

Итак, вы видите, что решение с использованием A = A(A ~= 0) является более быстрым из двух:)

Ответ 3

Я часто делал такие вещи. Поэтому я попытался написать простую функцию, которая легко "освобождает" нежелательные элементы. Это немного изменяет логику Matlab, но выглядит хорошо:

b = snip(a,'0')

вы можете найти файл функции по адресу: http://www.mathworks.co.uk/matlabcentral/fileexchange/41941-snip-m-snip-elements-out-of-vectorsmatrices

Он также работает со всеми другими элементами "x", наном или другими.

Ответ 4

b = a(find(a~=0))

Ответ 5

Почему не просто, a=a(~~a) или a(~a)=[]. Это эквивалентно другим подходам, но, конечно, менее ключевым штрихам.

Ответ 6

Данные

a=[0  3   0   0   7   10   3   0   1   0   7   7   1   7   4]

Do

aa=nonzeros(a)'

Результат

aa=[3   7   10   3   1   7   7   1   7   4]

Ответ 7

Вы можете использовать разреженный (a), который возвратит

(1,2) 1

(1,4) 3

Это позволяет вам сохранять информацию о том, где были использованы ненулевые записи.