如何在scipy稀疏矩阵上创建视图/ Python引用?

5 投票
1 回答
671 浏览
提问于 2025-04-16 18:55

我正在开发一个算法,这个算法需要使用一个很大的块对角稀疏矩阵的对角线和第一个副对角线的块(这个矩阵的大小将是e06 x e06)。

目前,我创建了一个字典,用来存储这些块,这样我就可以像操作矩阵一样访问这些块。比如说,B[0,0](5x5) 就代表矩阵A(20x20)的第一个块,假设每个块是5x5的,并且矩阵A的类型是sparse.lil

这个方法虽然可以用,但运行起来非常慢,效率低下,因为它会复制数据。这个问题让我很惊讶,具体可以参考这个链接:GetItem 方法

有没有办法只在字典中存储稀疏矩阵的视图?我希望能够修改内容,同时还能使用相同的标识符。如果这样做稍微慢一点也没关系,因为这只需要做一次。不同的块会有很多不同的尺寸和形状。

1 个回答

4

据我所知,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],依此类推。

撰写回答