How to create view / python link on scipy sparse matrix?

I am working on an algorithm that uses the diagonal and first off-diagonal blocks of a large (will be e06 x e06) block diagonal sparse matrix.

Now I am creating a dict that stores blocks in such a way that I can access the blocks in a matrix form. For example, B [0,0] (5x5) gives the first block of the matrix A(20x20), assuming 5x5 blocks and that the matrix Ais of type sparse.lil.

This works great, but runs too long. This is inefficient because it copies the data as this link showed my surprise: GetItem method

Is there a way to save a view only on a sparse matrix in a dict? I would like to change the contents and still use the same identifiers. This is normal if it takes a little longer, because it needs to be done only once. Blocks will have many different sizes and shapes.

+5
source share
1 answer

As far as I know, all the different sparse matrices in scipy.sparsereturn copies, not some kind of representation. (Some of them can be significantly faster than lil_matrixthough!)

One way to do what you want is to simply work with slicer objects. For instance:

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] ..

+4

All Articles