2011-06-03 106 views
5

我正在使用一个算法,该算法使用对角线和大对角线稀疏矩阵(将e06 x e06)的第一个非对角线块。如何在scipy稀疏矩阵上创建视图/ python引用?

现在我创建一个dict,以这种方式存储块,以便像矩阵那样访问块。例如,B [0,0](5x5)给出矩阵A(20x20)的第一个块,假设有5x5个块,并且该矩阵A的类型为sparse.lil

这工作正常,但需要很长时间运行。这是效率低下,因为它复制的数据,因为这个参考揭示了我的惊讶:GetItem Method

有没有办法只存储在稀疏矩阵视图在字典?我想更改内容并仍能够使用相同的标识符。如果花费一点时间,它应该只做一次,这很好。块将有许多不同的尺寸和形状。

回答

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],依此类推。

+1

不错,看起来只是我需要的东西,抱歉在延迟回答我试图修改代码接受一个矩阵不同大小的多个块。现在不要帮我,我想自己弄清楚:)。如果我遇到更多问题,我会回来。 谢谢 – Jonas 2011-06-07 15:50:29

+0

请注意,从版本0.11.0开始,SciPy有一个(块对角线函数)[docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.block_diag.html#scipy.sparse.block_diag]在这里有所帮助。 – drevicko 2016-02-25 11:15:52