2012-06-25 15 views
17

corro un qr factorization en numpy que devuelve una lista de ndarrays, a saber Q y R:eliminar cero líneas 2-D de matriz numpy

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

R es una matriz de dos dimensiones, después de haber pivotado cero líneas en el fondo (incluso probado para todos los ejemplos en mi conjunto de prueba):

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

. Ahora, quiero dividir en dos matrices RR_~:

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

y R_0:

[[ 0.   0.   0.  ]] 

(extracción de todas las líneas de cero). Parece estar cerca de esta solución: deleting rows in numpy array.

EDIT:
Aún más interesante: np.linalg.qr() devuelve un -matrix n x n. No, lo que yo hubiera esperado:

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

Respuesta

37

Uso np.all con un axis argumento:

>>> 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

¿qué ocurre si axis = 0? – denfromufa

+1

@denfromufa 'axis = 0' eliminaría todas las columnas * cero *. – ecatmur

+2

que es obvio, lo que es problemático es que este filtrado no se puede aplicar como es para 'axis = 0', en su lugar es necesario transponer – denfromufa

2

Debido a que los datos no son exactamente iguales a cero, es necesario fijar un valor umbral para el cero como 1E- 6, usa numpy.all con axis = 1 para verificar que las filas sean ceros o no. Use numpy.where y numpy.diff para obtener las posiciones divididas, y llame a numpy.split para dividir la matriz en una lista de matrices.

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

Usted piensa, 1e-6 debería ser lo suficientemente preciso para la mayoría de los propósitos? ¿Debo aprender este parámetro? –

+0

@MillaWell la precisión siempre depende de la aplicación. Por ejemplo, una precisión de un milímetro es muy buena para la ingeniería civil, pero muy pobre para la ingeniería mecánica, y algo absurda para la astronomía, por ejemplo. – heltonbiker

1

Si desea eliminar las filas que tienen entradas insignificantes, que haría uso de 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,:] 
Cuestiones relacionadas