Как создать представление view / python на скудной разреженной матрице? - PullRequest
5 голосов
/ 03 июня 2011

Я работаю над алгоритмом, который использует диагональные и первые недиагональные блоки большой (будет e06 x e06) диагональной разреженной матрицы блоков.

Прямо сейчас я создаю dict, который сохраняет блоки втаким образом, что я могу получить доступ к блокам в матрице, как моды.Например, B [0,0] (5x5) дает первый блок матрицы A (20x20), предполагая, что блоки 5x5 и матрица A имеет тип sparse.lil.

. Это работает нормально, ноУжасно долго слишком долго бегать.Это неэффективно, потому что он копирует данные, как это удивило мое упоминание: Метод GetItem

Есть ли способ сохранить представление в разреженной матрице в dict?Я хотел бы изменить содержание и по-прежнему иметь возможность использовать те же идентификаторы.Это хорошо, если это займет немного больше времени, поскольку это должно быть сделано только один раз.Блоки будут иметь много разных размеров и форм.

1 Ответ

4 голосов
/ 05 июня 2011

Насколько я знаю, все различные разреженные матрицы в scipy.sparse возвращают копии, а не какое-то представление. (Однако некоторые другие могут быть значительно быстрее, чем lil_matrix!)

Один из способов сделать то, что вы хотите, это просто работать с объектами слайса. Например:

import scipy.sparse

class SparseBlocks(object):
    def __init__(self, data, chunksize=5):
        self.data = data
        self.chunksize = chunksize
    def _convert_slices(self, slices):
        newslices = []
        for axslice in slices:
            if isinstance(axslice, slice):
                start, stop = axslice.start, axslice.stop
                if axslice.start is not None:
                    start *= self.chunksize
                if axslice.stop is not None:
                    stop *= self.chunksize
                axslice = slice(start, stop, None)
            elif axslice is not None:
                axslice = slice(axslice, axslice+self.chunksize)
            newslices.append(axslice)
        return tuple(newslices)

    def __getitem__(self, item):
        item = self._convert_slices(item)
        return self.data.__getitem__(item)
    def __setitem__(self, item, value):
        item = self._convert_slices(item)
        return self.data.__setitem__(item, value)

data = scipy.sparse.lil_matrix((20,20))
s = SparseBlocks(data)
s[0,0] = 1
print s.data

Теперь, когда мы модифицируем s[whatever], он будет модифицировать s.data соответствующего чанка. Другими словами, s[0,0] вернет или установит s.data[:5, :5] и т. Д.

...