38 votes

Comment supprimer les composants zéro d'un vecteur en Matlab ?

J'ai un vecteur par exemple

a = [0 1 0 3]

Je veux transformer a en b qui est égal à b = [1 3].

Comment puis-je faire cela en général? J'ai un vecteur avec certaines composantes nulles et je veux supprimer les zéros et laisser uniquement les chiffres non nuls?

82voto

Si vous souhaitez simplement supprimer les zéros, en laissant les non-nuls derrière dans a, alors la meilleure solution est

a(a==0) = [];

Cela supprime les éléments zéro, en utilisant une approche d'indexation logique en MATLAB. Lorsque l'indice d'un vecteur est un vecteur booléen de la même longueur que le vecteur, MATLAB peut l'utiliser pour l'indexer. C'est donc équivalent à

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

Et, lorsque vous définissez certains éléments du tableau sur [] en MATLAB, la convention est de les supprimer.

Si vous souhaitez mettre les zéros dans un nouveau résultat b, tout en laissant a inchangé, la meilleure façon est probablement

b = a(a ~= 0);

Encore une fois, l'indexation logique est utilisée ici. Vous auriez pu utiliser la version équivalente (en termes de résultat) de

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

mais mlint finira par signaler la ligne comme étant plus efficace en termes d'indexation purement logique, et donc plus appropriée.

Comme toujours, méfiez-vous des tests EXACTS pour zéro ou pour tout nombre, si vous auriez accepté des éléments de a qui étaient dans une tolérance epsilon de zéro. Faites ces tests comme ceci

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

Cela ne conserve que les éléments de a qui sont au moins aussi grands que votre tolérance.

8voto

tim Points 2923

Je suis tombé sur ce problème et j'ai voulu trouver quelque chose sur les performances, mais je n'ai pas pu, donc j'ai écrit un script de benchmarking par moi-même :

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

% Démarrage :
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

Donc, vous voyez, la solution utilisant A = A(A ~= 0) est la plus rapide des deux :)

4voto

Nicolas Points 21

J'ai souvent fini par faire des choses comme ça. C'est pourquoi j'ai essayé d'écrire une fonction simple qui «supprime» les éléments non désirés de manière facile. Cela rend un peu à l'envers la logique de matlab, mais ça a l'air bien :

b = snip(a,'0')

vous pouvez trouver le fichier de la fonction à l'adresse : http://www.mathworks.co.uk/matlabcentral/fileexchange/41941-snip-m-snip-elements-out-of-vectorsmatrices

Ça fonctionne aussi avec tous les autres éléments 'x', nan ou autres.

3voto

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

2voto

Humberto77 Points 33

Pourquoi ne pas simplement, a=a(~~a) ou a(~a)=[]. C'est équivalent aux autres méthodes mais certainement avec moins de touches.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X