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

Если я использую формат sparse.lil_matrix, как можно легко и эффективно удалить столбец из матрицы?

  • Python: чтение бинарного файла Fortran с использованием numpy или scipy
  • Установка данных в дистрибутивы?
  • Построение матрицы «свернутых» строк эффективно в Numpy
  • Быстрый алгоритм b-сплайна с numpy / scipy
  • Создание массива в numpy / scipy путем итерации в Python?
  • Сортировка массивов в NumPy по столбцам
  • scipy, lognormal distribution - параметры
  • Numpy: разделите каждую строку на векторный элемент
  • 6 Solutions collect form web for “Как можно эффективно удалить столбец из разреженной матрицы?”

    Я сам этого хотел, и, по правде говоря, еще нет встроенного способа сделать это. Вот как это сделать. Я решил создать подкласс lil_matrix и добавить функцию remove_col. Если вы хотите, вы можете вместо этого добавить функцию removeecol в класс lil_matrix в файле lib/site-packages/scipy/sparse/lil.py Вот код:

     from scipy import sparse from bisect import bisect_left class lil2(sparse.lil_matrix): def removecol(self,j): if j < 0: j += self.shape[1] if j < 0 or j >= self.shape[1]: raise IndexError('column index out of bounds') rows = self.rows data = self.data for i in xrange(self.shape[0]): pos = bisect_left(rows[i], j) if pos == len(rows[i]): continue elif rows[i][pos] == j: rows[i].pop(pos) data[i].pop(pos) if pos == len(rows[i]): continue for pos2 in xrange(pos,len(rows[i])): rows[i][pos2] -= 1 self._shape = (self._shape[0],self._shape[1]-1) 

    Я пробовал это и не вижу никаких ошибок. Я, конечно, думаю, что это лучше, чем нарезать колонку, которая, как я знаю, просто создает новую матрицу.

    Я также решил сделать функцию removerow, но я не думаю, что это так же хорошо, как и удаление. Я ограничен тем, что не смог удалить одну строку из ndarray так, как хотелось бы. Здесь removerow, который может быть добавлен к вышеуказанному классу

      def removerow(self,i): if i < 0: i += self.shape[0] if i < 0 or i >= self.shape[0]: raise IndexError('row index out of bounds') self.rows = numpy.delete(self.rows,i,0) self.data = numpy.delete(self.data,i,0) self._shape = (self._shape[0]-1,self.shape[1]) 

    Возможно, я должен представить эти функции в репозиторий Scipy.

    Гораздо проще и быстрее. Возможно, вам даже не понадобится преобразование в csr, но я точно знаю, что он работает с csr разреженными матрицами, и преобразование между ними не должно быть проблемой.

     from scipy import sparse x_new = sparse.lil_matrix(sparse.csr_matrix(x)[:,col_list]) 

    Я новичок в python, поэтому мой ответ, вероятно, неверен, но мне было интересно, почему что-то вроде следующего не будет эффективным?

    Допустим, ваш lil_matrix называется mat и вы хотите удалить i-й столбец:

     mat=hstack( [ mat[:,0:i] , mat[:,i+1:] ] ) 

    Теперь после этого матрица превратится в coo_matrix, но вы можете вернуть ее обратно в lil_matrix.

    Хорошо, я понимаю, что это должно будет создать две матрицы внутри hstack, прежде чем он будет присваивать переменной mat, так что это будет похоже на оригинальную матрицу плюс еще одну в одно и то же время, но я думаю, если разреженность достаточно велика то я думаю, что не должно быть проблем с памятью (поскольку память (и время) является причиной использования разреженных матриц).

    Для разреженной матрицы csr (X) и списка индексов для drop (index_to_drop):

     to_keep = list(set(xrange(X.shape[1]))-set(index_to_drop)) new_X = X[:,to_keep] 

    Легко преобразовать lil_matrices в csr_matrices. Проверьте tocsr () в документации lil_matrix

    Обратите внимание, однако, что переход от csr к lil-матрицам с использованием tolil () стоит дорого. Таким образом, этот выбор хорош, когда вам не требуется иметь матрицу в формате lil.

     def removecols(W, col_list): if min(col_list) = W.shape[1]: raise IndexError('column index out of bounds') rows = W.rows data = W.data for i in xrange(M.shape[0]): for j in col_list: pos = bisect_left(rows[i], j) if pos == len(rows[i]): continue elif rows[i][pos] == j: rows[i].pop(pos) data[i].pop(pos) if pos == len(rows[i]): continue for pos2 in xrange(pos,len(rows[i])): rows[i][pos2] -= 1 W._shape = (W._shape[0], W._shape[1]-len(col_list)) return W 

    Просто переписал свой код для работы с col_list в качестве ввода – возможно, это будет полезно для кого-то.

    Рассматривая заметки для каждой разреженной матрицы, в частности, в нашем случае это матрица csc, она имеет следующие преимущества, перечисленные в документации [1]

    • эффективные арифметические операции CSC + CSC, CSC * CSC и т. д.
    • эффективная сортировка столбцов
    • быстрые матричные векторные продукты (CSR, BSR может быть быстрее)

    Если у вас есть индексы столбцов, которые вы хотите удалить, просто используйте нарезку. Для удаления строк используется csr-матрица, так как она эффективна в разрезе строк

    Python - лучший язык программирования в мире.