2012-06-25 2 views
17

я запустить qr factorization в numpy, который возвращает список ndarrays, а именно Q и R:удалить нулевые строки 2-D NumPy массива

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

R является двумерный массив, будучи повернута нулевые строки в (даже доказанные для всех примеров в моем испытательном наборе):

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

. Теперь я хочу, чтобы разделить R в двух матрицах R_~:

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

и R_0:

[[ 0.   0.   0.  ]] 

(извлечение всех нулевые строки). Это похоже на это решение: deleting rows in numpy array.

EDIT:
Еще более интересно: np.linalg.qr() возвращает n x n -матрица. Не то, что я ожидал бы:

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

ответ

37

np.all Использования с axis аргументом:

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

Что делать, если ось = 0? – denfromufa

+1

@denfromufa 'axis = 0' удалит все нулевые * столбцы *. – ecatmur

+2

Очевидно, что проблематично то, что эта фильтрация не может быть применена, как и для 'axis = 0', вместо этого требуется транспонирование – denfromufa

2

Поскольку данные не равен нуль точно, нам нужно установить пороговое значение для нуля, таких как 1e- 6, используйте numpy.all с осью = 1, чтобы проверить, что строки являются нулями или нет. Используйте numpy.where и numpy.diff, чтобы получить разделенные позиции, и вызовите numpy.split, чтобы разбить массив на список массивов.

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

Вы думаете, 1е-6 должен быть достаточно точным для большинства целей? Должен ли я изучить этот параметр? –

+0

@MillaWell точность всегда зависит от приложения. Например, точность одного миллиметра очень хороша для гражданского строительства, но очень бедна для машиностроения и, например, несколько абсурдна для астрономии. – heltonbiker

1

Если вы хотите, чтобы устранить те строки, которые имеют незначительные записи, я хотел бы использовать 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,:] 
Смежные вопросы