Как эффективно удалять столбцы из разреженной матрицы, содержащей только нули?

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

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

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

Ответ 1

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

Но это разреженная матрица, которая не поддерживает логическое индексирование, а также не даст вам то, что вы хотите, если попробуете X!=0 - он просто возвращает одно логическое значение, которое, кажется, возвращает только 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]

Ответ 2

Это выглядит так, но не идеально эффективно:

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

Ответ 3

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

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

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

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

idx = np.unique(sparse.find(x)[1], return_counts=True)
x[:, idx[0][idx[1] > n]]