2009-04-10 11 views

risposta

16

Un modo:

x(x == 0) = []; 

Una nota sui tempi:

Come indicato da woodchips, questo metodo sembra lenta rispetto a quella usata da KitsuneYMG. Ciò è stato notato anche da Loren in uno dei suoi MathWorks blog posts. Poiché hai menzionato di doverlo fare migliaia di volte, potresti notare una differenza, nel qual caso dovrei provare prima con x = x(x~=0);.

ATTENZIONE: Attenzione se si utilizzano numeri non interi. Se, ad esempio, hai un numero molto piccolo che vorresti considerare abbastanza vicino a zero in modo che venga rimosso, il codice sopra non lo rimuoverà. Solo esatti zeri vengono rimossi. Di seguito vi aiuterà a rimuovere anche i numeri "abbastanza vicino" a zero:

tolerance = 0.0001; % Choose a threshold for "close enough to zero" 
x(abs(x) <= tolerance) = []; 
+0

Questo non riesce a numeri negativi Prova 'abs (x) <= tolerance' – KitsuneYMG

+0

La x <= tolleranza escluderebbe i numeri in virgola mobile negativi. Probabilmente dovresti espandere il confronto per essere x> = tolleranza e x <= tolleranza. L'operatore logico e in MATLAB mi sfugge in questo momento. –

+0

Ho corretto la risposta per rimuovere qualsiasi valore abbastanza vicino a zero dalla direzione negativa o positiva. – gnovice

11

Giusto per essere diversi:

x=x(x~=0); 

o

x=x(abs(x)>threshold); 

Questo ha il vantaggio di lavorare su complessa numeri anche

3

Ecco un altro modo

y = x (find (x))

Lo lascerò a voi per capire l'efficienza relativa dei vari approcci che provate - scrivete e fateci sapere a tutti.

11

Queste sono le tre soluzioni comuni. Aiuta a vedere la differenza.

x = round(rand(1,15000)); 

y = x; 

tic,y(y==0) = [];toc 

Elapsed time is 0.004398 seconds. 

y = x; 

tic,y = y(y~=0);toc 

Elapsed time is 0.001759 seconds. 

y = x; 

tic,y = y(find(y));toc 

Elapsed time is 0.003579 seconds. 

Come si può vedere, il modo più economico è l'indice logico diretto, selezionando gli elementi da conservare. Il risultato è più costoso, dal momento che MATLAB trova questi elementi, restituendone un elenco e quindi indicizzandoli nel vettore.

+0

Wow! Quei numeri sono giusti? Potrei giurare che "y (y == 0) = [];" e "y = y (y ~ = 0);" erano comparabili tra loro in termini di velocità. Dovrò controllare di nuovo i miei numeri. – gnovice

+0

Non importa ... Ho appena trovato un post sul blog di Loren alla matematica che risolve esattamente questo problema, e sembra essere d'accordo con i tuoi numeri. – gnovice

+0

@gnovice Si noti che ora è possibile usare '[~, ~, y] = find (y)' che dovrebbe fornire prestazioni simili alla soluzione con l'indicizzazione logica. –

0
x = [0 0 0 1 1 0 5 0 7 0] 
y = [0 2 0 1 1 2 5 2 7 0] 

Poi x2 e y2 può essere ottenuto come:

x2=x(~(x==0 & y==0)) 
y2=y(~(x==0 & y==0)) 

x2 = [0  1  1  0  5  0  7] 
y2 = [2  1  1  2  5  2  7] 

Spero che questo aiuti!

2

Anche se i miei risultati di temporizzazione non sono conclusivi per se è significativamente più veloce, questo sembra essere l'approccio più semplice e veloce:

y = nonzeros(y) 
Problemi correlati