2012-06-25 20 views
17

uruchomić qr factorization w numpy która zwraca lista ndarrays, mianowicie Q i R:usunąć zerowe linie 2-D numpy tablicy

>>> [q,r] = np.linalg.qr(np.array([1,0,0,0,1,1,1,1,1]).reshape(3,3)) 

R jest dwuwymiarową tablicą, że obraca zerowej linii w dno (nawet dla wszystkich przykładów z mojego zestawu testowego):

>>> print r 
[[ 1.41421356 0.70710678 0.70710678] 
[ 0.   1.22474487 1.22474487] 
[ 0.   0.   0.  ]] 

. Teraz chcę podzielić R w dwóch macierzach R_~:

[[ 1.41421356 0.70710678 0.70710678] 
[ 0.   1.22474487 1.22474487]] 

i R_0:

[[ 0.   0.   0.  ]] 

(wydobywania wszystkie zerowej linii). Wydaje się być blisko tego rozwiązania: deleting rows in numpy array.

EDYTOWANIE: Jeszcze ciekawiej: np.linalg.qr() zwraca matrycę n x n. Nie, co by się było spodziewać:

A := n x m 
Q := n x m 
R := n x m 

Odpowiedz

37

np.all Korzystanie z axis argumentu:

>>> r[np.all(r == 0, axis=1)] 
array([[ 0., 0., 0.]]) 
>>> r[~np.all(r == 0, axis=1)] 
array([[-1.41421356, -0.70710678, -0.70710678], 
     [ 0.  , -1.22474487, -1.22474487]]) 
+1

co jeśli oś = 0? – denfromufa

+1

@denfromufa 'axis = 0' usunie wszystkie zero * kolumn *. – ecatmur

+2

, co jest oczywiste, problematyczne jest to, że tego filtrowania nie można zastosować tak, jak dla "osi = 0", zamiast tego konieczna jest transpozycja – denfromufa

2

Ponieważ dane nie są równe zeru dokładnie, musimy ustawić wartość progową dla zerowy takich jak 1e- 6, użyj numpy.all z axis = 1, aby sprawdzić, czy wiersze są zerami, czy nie. Użyj numpy.where i numpy.diff, aby uzyskać podzielone pozycje, i wywołaj numpy.split, aby podzielić tablicę na listę tablic.

import numpy as np 
[q,r] = np.linalg.qr(np.array([1,0,0,0,1,1,1,1,1]).reshape(3,3)) 
mask = np.all(np.abs(r) < 1e-6, axis=1) 
pos = np.where(np.diff(mask))[0] + 1 
result = np.split(r, pos) 
+0

Myślisz, 1e-6 powinien być wystarczająco precyzyjny dla większości celów? Czy powinienem nauczyć się tego paramateru? –

+0

@MillaWell dokładność zawsze zależy od aplikacji. Na przykład precyzja jednego milimetra jest bardzo dobra dla inżynierii lądowej, ale bardzo słaba dla inżynierii mechanicznej, a na przykład dla astronomii nieco absurdalna. – heltonbiker

1

Jeśli chcesz wyeliminować wiersze, które mają znikome wpisy, użyję np.allclose.

zero_row_indices = [i for i in r.shape[0] if np.allclose(r[i,:],0)] 
nonzero_row_indices =[i for i in r.shape[0] if not np.allclose(r[i,:],0)] 
r_new = r[nonzero_row_indices,:]