我正在尝试操作稀疏矩阵中的一些数据。一旦我创建了一个,我如何在其中添加/更改/更新值?这看起来非常基本,但我在稀疏矩阵类的文档中或在Web上找不到它。我想我错过了至关重要的事情。
这是我尝试这样做的失败方式,与普通数组相同。
>>> from scipy.sparse import bsr_matrix
>>> A = bsr_matrix((10,10))
>>> A[5][7] = 6
Traceback (most recent call last):
File "<pyshell#11>", line 1, in <module>
A[5][7] = 6
File "C:\Python27\lib\site-packages\scipy\sparse\bsr.py", line 296, in __getitem__
raise NotImplementedError
NotImplementedError
答案 0 :(得分:5)
有几种稀疏矩阵格式。有些更适合索引。实现它的是lil_matrix
。
Al = A.tolil()
Al[5,7] = 6 # the normal 2d matrix indexing notation
print Al
print Al.A # aka Al.todense()
A1 = Al.tobsr() # if it must be in bsr format
每种格式的文档都表明它擅长什么,哪些不好。但它没有一个整齐的清单,列出哪些操作定义了哪些。
Advantages of the LIL format
supports flexible slicing
changes to the matrix sparsity structure are efficient
...
Intended Usage
LIL is a convenient format for constructing sparse matrices
...
dok_matrix
也实现了索引。
coo_matrix
的基础数据结构很容易理解。它本质上是coo_matrix((data, (i, j)), [shape=(M, N)])
定义的参数。要创建相同的矩阵,您可以使用:
sparse.coo_matrix(([6],([5],[7])), shape=(10,10))
如果您有更多分配,请构建更大的data
,i
,j
列表(或1d数组),并在完成构建稀疏矩阵时使用。
答案 1 :(得分:2)
bsr的文档在bsr matrix,csr的文档在csr matrix。在转移到bsr之前理解csr可能是值得的。唯一的区别是bsr的条目本身就是矩阵,而csr中的基本单位是标量。
我不知道在创建矩阵后是否有超级简单的方法来操纵矩阵,但这里有一些你正在尝试做的事情的例子,
import numpy as np
from scipy.sparse import bsr_matrix, csr_matrix
row = np.array( [5] )
col = np.array( [7] )
data = np.array( [6] )
A = csr_matrix( (data,(row,col)) )
这是一种简单的语法,您可以在其中列出数组data
中矩阵中所需的所有数据,然后使用row
和col
指定数据的去向。请注意,这将使矩阵尺寸足够大,以便将元素保存在最大的行和列中(在本例中为6x8矩阵)。您可以使用todense()
方法以标准形式查看矩阵。
A.todense()
但是,您无法使用此模式动态操作矩阵。你可以做的是修改矩阵的原始scipy表示。这涉及3个属性indices
,indptr
和data
。首先,我们可以检查我们已经创建的数组的这些属性的值。
>>> print A.data
array([6])
>>> print A.indices
array([7], dtype=int32)
>>> print A.indptr
array([0, 0, 0, 0, 0, 0, 1], dtype=int32)
data
和以前一样,是矩阵中我们想要的一维数组。不同之处在于,此数据的位置现在由indices
和indptr
而不是row
和col
指定。 indices
非常简单。它只是每个数据条目所在列的列表。它将始终具有相同的大小和data
数组。 indptr
有点棘手。它允许数据结构知道每个数据条目所在的行。引用文档,
行
中i
的列索引存储在indices[indptr[i]:indptr[i+1]]
从这个定义中我们可以看到indptr
的大小总是矩阵中的行数+ 1.需要一点时间来习惯它,但是要处理每一行的值会给你一些直觉。请注意,所有条目都是零,直到最后一个。这意味着行i=0-4
的列索引将存储在indices[0:0]
中,即空数组。这是因为这些行都是零。最后,在最后一行i=5
,我们得到indices[0:1]=7
,告诉我们数据条目data[0:1]
位于第5行第7列。
现在假设我们想在第2行第4列添加值10.我们首先将它放入data
属性,
A.data = np.array( [10,6] )
接下来我们更新indices
以指示第10列将在
A.indices = np.array( [4,7], dtype=np.int32 )
最后我们通过修改indptr
A.indptr = np.array( [0,0,0,1,1,1,2], dtype=np.int32 )
您必须使数据类型为indices
和indptr
np.int32
。可视化indptr
中的内容的一种方法是,当您从具有数据的行的i
移动到i+1
时,数字会发生变化。另请注意,这些数组可用于构造稀疏矩阵
B = csr_matrix( (data,indices,indptr) )
如果它像你尝试的那样简单地索引到数组中会很容易,但是实现还没有。这应该足以让你至少开始。