2009-04-10 9 views

Odpowiedz

16

Jednym ze sposobów:

x(x == 0) = []; 

Uwaga na terminy:

Jak wspomniano przez woodchips, metoda ta wydaje się powolny w porównaniu do stosowanego przez KitsuneYMG. Zostało to również zauważone przez Loren w jednym z jej MathWorks blog posts. Ponieważ wspomniałeś o konieczności zrobienia tego tysiące razy, możesz zauważyć różnicę, w którym to przypadku najpierw spróbowałbym uzyskać x = x(x~=0);.

OSTRZEŻENIE: Pamiętaj, jeśli używasz liczb niecałkowitych. Jeśli, na przykład, masz bardzo małą liczbę, którą chciałbyś rozważyć wystarczająco blisko do zera, aby ją usunąć, powyższy kod jej nie usunie. Usuwane są tylko zera dokładne. Następujące pomoże również usunąć numery "wystarczająco blisko" do zera:

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

To nie na liczbach ujemnych Spróbuj 'abs (x) <= tolerance' – KitsuneYMG

+0

Tolerancja x <= wyklucza ujemne liczby zmiennoprzecinkowe. Prawdopodobnie będziesz musiał rozszerzyć porównanie na x> = tolerancja i x <= tolerancja. Operator logicznego i matlab ucieka mi w tej chwili. –

+0

Poprawiłem odpowiedź, aby usunąć dowolną wartość wystarczająco zbliżoną do zera z ujemnego lub dodatniego kierunku. – gnovice

11

Wystarczy być różne:

x=x(x~=0); 

lub

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

Ma to bonus działa na kompleks numery też

3

Oto inny sposób:

y = x (znajdź (x))

Zostawię to dla ciebie, aby dowiedzieć się względną efektywność różnych podejść, które wypróbujesz - pisz i daj nam znać.

11

To są trzy typowe rozwiązania. Pomaga dostrzec różnicę.

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. 

Jak widać, najtańszym sposobem jest bezpośredni indeks logiczny, wybierając elementy, które mają zostać zachowane. Odkrycie jest droższe, ponieważ matlab znajduje te elementy, zwracając ich listę, a następnie indeksuje do wektora.

+0

Wow! Czy te liczby są prawidłowe? Mógłbym przysiąc, że "y (y == 0) = [];" i "y = y (y ~ = 0);" były porównywalne do siebie pod względem prędkości. Będę musiał ponownie sprawdzić moje liczby. – gnovice

+0

Nieważne ... Właśnie znalazłem wpis na blogu autorstwa Lorena, który opisuje dokładnie ten problem i wydaje się, że zgadza się z twoimi numerami. – gnovice

+0

@ gnovice Zauważ, że możesz teraz użyć '[~, ~, y] = find (y)', który powinien dać podobną wydajność rozwiązaniu z logicznym indeksowaniem. –

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

Następnie x2 i y2 można otrzymać jako:

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] 

nadzieję, że to pomaga!

2

Choć moje wyniki czasowe nie są rozstrzygające, czy jest to znacznie szybciej, to wydaje się być najszybszy i najprostszy podejście:

y = nonzeros(y)