Как удалить нулевые компоненты в векторе в Matlab? - PullRequest
37 голосов
/ 14 апреля 2010

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

a = [0 1 0 3]

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

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

Ответы [ 7 ]

81 голосов
/ 14 апреля 2010

Если вы просто хотите удалить нули, оставив ненулевые в 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, которые по крайней мере равны вашему допуску.

8 голосов
/ 23 января 2012

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

% 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) является более быстрым из двух:)

4 голосов
/ 03 июня 2013

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

b = snip(a,'0')

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

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

3 голосов
/ 14 апреля 2010
b = a(find(a~=0))
2 голосов
/ 21 марта 2017

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

(1,2) 1

(1,4) 3

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

2 голосов
/ 16 сентября 2015

Данные

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

У

aa=nonzeros(a)'

Результат

aa=[3   7   10   3   1   7   7   1   7   4]
2 голосов
/ 03 октября 2014

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

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