我在Scipy中有一个巨大的稀疏矩阵,我想用给定的值(假设是-1
)替换内部的许多元素。
有比使用
更有效的方法吗?SM[[rows],[columns]]=-1
下面是一个例子:
Nr=seg.shape[0] #size ~=50000
Im1=sparse.csr_matrix(np.append(np.array([-1]),np.zeros([1,Nr-1])))
Im1=sparse.csr_matrix(sparse.vstack([Im1,sparse.eye(Nr)]))
Im1[prev[1::]-1,Num[1::]-1]=-1 # this line is very slow
Im2=sparse.vstack([sparse.csr_matrix(np.zeros([1,Nr])),sparse.eye(Nr)])
IM=sparse.hstack([Im1,Im2]) #final result
我已经玩了你的sparse
数组。我鼓励您在较小的大小上进行计时,以了解不同的方法和稀疏类型的行为。我喜欢在Ipython
中使用timeit
Nr=10 # seg.shape[0] #size ~=50000
Im2=sparse.vstack([sparse.csr_matrix(np.zeros([1,Nr])),sparse.eye(Nr)])
Im2
第一行为零,其余部分为偏移对角线。因此,从一个空的稀疏矩阵开始是更简单的,尽管不是更快:
X = sparse.vstack([sparse.csr_matrix((1,Nr)),sparse.eye(Nr)])
或者使用diags
直接构造偏移对角线:
X = sparse.diags([1],[-1],shape=(Nr+1, Nr))
Im1
是类似的,除了在(0,0)
槽位有一个-1
。如何堆叠两个对角矩阵?
X = sparse.vstack([sparse.diags([-1],[0],(1,Nr)),sparse.eye(Nr)])
或使偏移对角线(复制Im2
?),并修改[0,0]
。csr
矩阵给出了一个效率警告,建议使用lil
格式。但是,转换tolil()
确实需要一些时间。
X = sparse.diags([1],[-1],shape=(Nr+1, Nr)).tolil()
X[0,0] = -1 # slow warning with csr
让我们试试你的大插入:
prev = np.arange(Nr-2) # what are these like?
Num = np.arange(Nr-2)
Im1[prev[1::]-1,Num[1::]-1]=-1
使用Nr=10
和各种Im1
格式:
lil - 267 us
csr - 1.44 ms
coo - not supported
todense - 25 us
好的,我选择了prev
和Num
,这样我最终修改了Im1
的对角线。在这种情况下,从一开始就构造这些对角线会更快。
X2=Im1.todia()
print X2.data
[[ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[-1. -1. -1. -1. -1. -1. -1. 0. 0. 0.]]
print X2.offsets
[-1 0]
您可能需要了解各种稀疏格式是如何存储的。csr
和csc
有点复杂,用于快速线性代数运算。lil
、dia
、coo
比较容易理解