2012-05-19 6 views
10

Каков наилучший способ эффективного удаления столбцов из разреженной матрицы, содержащей только нули. У меня есть матрица, которую я создал и заполненный данными:Как эффективно удалять столбцы из разреженной матрицы, содержащей только нули?

matrix = sp.sparse.lil_matrix((100, 100)) 

теперь я хочу, чтобы удалить ~ 20 последних столбцов, которые содержат только нулевые данные. Как я могу это сделать?

+3

Вы обязались использовать lil_matrix? Согласно scipy docs, это не эффективно для разбиения столбцов - вместо этого вы можете использовать csc_matrix. См. Http://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.lil_matrix.html и http://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse. csc_matrix.html –

+0

Спасибо за помощь. Да, csr или csc также прекрасны. – turtle

+0

@turtle это ответ на ваш вопрос? – gabe

ответ

8

Если бы это было просто NumPy массив, X, то можно сказать, X!=0 который даст вам булево массив той же формы, как X , а затем вы можете индекс X с булевой массива, т.е. non_zero_entries = X[X!=0]

Но это разреженная матрица, которая не поддерживает логическое индексирование, а также не даст вам то, что вы хотите, если вы пытаетесь X!=0 - он просто возвращает петь le boolean значение, которое, кажется, возвращает true только в том случае, если они являются одинаковой матрицей (в памяти).

Что вы хотите, это метод nonzero от numpy.

import numpy as np 
from scipy import sparse 

X = sparse.lil_matrix((100,100)) # some sparse matrix 
X[1,17] = 1 
X[17,17] = 1 
indices = np.nonzero(X) # a tuple of two arrays: 0th is row indices, 1st is cols 
X.tocsc()[indices] # this just gives you the array of all non-zero entries 

Если вы хотите только полные столбцы, где есть ненулевые записи, то просто возьмите 1-й из индексов. Кроме того вы должны учитывать повторяющиеся индексы (если есть несколько записей в столбце):

columns_non_unique = indices[1] 
unique_columns = sorted(set(columns_non_unique)) 
X.tocsc()[:,unique_columns] 
+3

Я использовал следующее, чтобы извлечь только столбцы с ненулевыми элементами: 'matrix [:, np.unique (alldata.nonzero() [1])]' – canzar

+0

Это замечательно и компактно. В значительной степени то же самое, за исключением того, что вы используете уникальный уникальный параметр numpy вместо 'sorted (set (columns))'. – gabe

+1

, чтобы быть ясными, большинство разреженных матриц имеют метод «.nonzero», который работает одинаково и намного быстрее, чем 'np.nonzero (sparse_matrix)'. Тем не менее, полезный ответ. –

1

Это очень похоже на пути, хотя и не идеально эффективным:

matrix = matrix[0:100,0:80] 
+0

К сожалению, количество нулевых столбцов не всегда фиксировано. Мне нужен способ сделать это так, что если бы было 35 нулевых столбцов или 10 нулевых столбцов, программа все равно работала бы. – turtle

0

Можно также использовать scipy.sparse.find() , чтобы получить расположение всех ненулевых элементов в разреженной матрице.

[1]-я запись в возвращаемом значении представляет собой массив чисел с номерами. Принятие уникальных значений из этого массива дает индексы ненулевых столбцов. Подстановка исходной разреженной матрицы этими столбцами дает ненулевые столбцы.

x[:,np.unique(sparse.find(x)[1])] 

можно расширить это, чтобы найти столбцы с по крайней мере п записей:

idx = np.unique(sparse.find(x)[1], return_counts=True) 
x[:, idx[0][idx[1] > n]] 
Смежные вопросы