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

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

15
задан ThinkingStiff 1 February 2013 в 22:35
поделиться

2 ответа

Я сам хотел этого, и, по правде говоря, еще нет отличного встроенного способа сделать это. Вот способ сделать это. Я решил создать подкласс lil_matrix и добавить функцию remove_col. Если вы хотите, вы можете вместо этого добавить функцию removecol к классу 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, но не думаю, что она так же хороша, как removecol. Я ограничен тем, что не могу удалить одну строку из 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.

8
ответ дан 1 December 2019 в 02:55
поделиться

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 в качестве входных данных - может быть, это будет кому-то полезно.

0
ответ дан 1 December 2019 в 02:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: