从稀疏coo_matrix得到的对角稀疏矩阵
Diagonal sparse matrix obtained from a sparse coo_matrix
我使用 coo_matrix
格式在 Python 中构建了一些稀疏矩阵 M
。我想找到一种有效的计算方法:
A = M + M.T - D
其中 D
是 M
对其对角线的限制(M
可能非常大)。我找不到在保持 coo_matrix
格式的同时有效构建 D
的方法。有什么想法吗?
D = scipy.sparse.spdiags(coo_matrix.diagonal(M),0,M.shape[0],M.shape[0])
可以解决吗?
你可能想要
from scipy.sparse import diags
D = diags(M.diagonal(), 0, format='coo')
这仍将构建一个 M 大小的一维数组作为中间步骤,但这可能不会太糟糕。
我想出了一个更快的 coo
对角线:
msk = M.row==M.col
D1 = sparse.coo_matrix((M.data[msk],(M.row[msk],M.col[msk])),shape=M.shape)
sparse.tril
将此方法与 mask = A.row + k >= A.col
(sparse/extract.py
)
一起使用
有时 (100,100) M
(和 M1 = M.tocsr()
)
In [303]: timeit msk=M.row==M.col; D1=sparse.coo_matrix((M.data[msk],(M.row[msk],M.col[msk])),shape=M.shape)
10000 loops, best of 3: 115 µs per loop
In [305]: timeit D=sparse.diags(M.diagonal(),0)
1000 loops, best of 3: 358 µs per loop
所以 coo
获得对角线的方法很快,至少对于这个非常稀疏的小矩阵来说(对角线只有 1 次)
如果我从 csr
形式开始,diags
会更快。那是因为 .diagonal
以 csr
格式工作:
In [306]: timeit D=sparse.diags(M1.diagonal(),0)
10000 loops, best of 3: 176 µs per loop
但是创建 D
只是整个计算的一小部分。同样,使用 M1
更快。总和以 csr
格式完成。
In [307]: timeit M+M.T-D
1000 loops, best of 3: 1.35 ms per loop
In [308]: timeit M1+M1.T-D
1000 loops, best of 3: 1.11 ms per loop
完成整个事情的另一种方法是利用 coo
允许重复的 i,j
值这一事实,这些值将在转换为 csr
格式时求和。因此,您可以将 M
的 row, col, data
数组与 M.T
的数组堆叠在一起(请参阅 M.transpose
了解它们的构造方式),以及 D
的掩码值。 (或者可以从 M
或 M.T
中删除屏蔽的对角线)
例如:
def MplusMT(M):
msk=M.row!=M.col;
data=np.concatenate([M.data, M.data[msk]])
rows=np.concatenate([M.row, M.col[msk]])
cols=np.concatenate([M.col, M.row[msk]])
MM=sparse.coo_matrix((data, (rows, cols)), shape=M.shape)
return MM
# alt version with a more explicit D
# msk=M.row==M.col;
# data=np.concatenate([M.data, M.data,-M.data[msk]])
MplusMT
写的非常快,因为它只是做数组连接,而不是求和。为此,我们必须将其转换为 csr
矩阵。
MplusMT(M).tocsr()
这需要相当长的时间。在我的有限测试中,这种方法仍然比 M+M.T-D
快 2 倍以上。因此它是构建复杂稀疏矩阵的潜在工具。
我使用 coo_matrix
格式在 Python 中构建了一些稀疏矩阵 M
。我想找到一种有效的计算方法:
A = M + M.T - D
其中 D
是 M
对其对角线的限制(M
可能非常大)。我找不到在保持 coo_matrix
格式的同时有效构建 D
的方法。有什么想法吗?
D = scipy.sparse.spdiags(coo_matrix.diagonal(M),0,M.shape[0],M.shape[0])
可以解决吗?
你可能想要
from scipy.sparse import diags
D = diags(M.diagonal(), 0, format='coo')
这仍将构建一个 M 大小的一维数组作为中间步骤,但这可能不会太糟糕。
我想出了一个更快的 coo
对角线:
msk = M.row==M.col
D1 = sparse.coo_matrix((M.data[msk],(M.row[msk],M.col[msk])),shape=M.shape)
sparse.tril
将此方法与 mask = A.row + k >= A.col
(sparse/extract.py
)
有时 (100,100) M
(和 M1 = M.tocsr()
)
In [303]: timeit msk=M.row==M.col; D1=sparse.coo_matrix((M.data[msk],(M.row[msk],M.col[msk])),shape=M.shape)
10000 loops, best of 3: 115 µs per loop
In [305]: timeit D=sparse.diags(M.diagonal(),0)
1000 loops, best of 3: 358 µs per loop
所以 coo
获得对角线的方法很快,至少对于这个非常稀疏的小矩阵来说(对角线只有 1 次)
如果我从 csr
形式开始,diags
会更快。那是因为 .diagonal
以 csr
格式工作:
In [306]: timeit D=sparse.diags(M1.diagonal(),0)
10000 loops, best of 3: 176 µs per loop
但是创建 D
只是整个计算的一小部分。同样,使用 M1
更快。总和以 csr
格式完成。
In [307]: timeit M+M.T-D
1000 loops, best of 3: 1.35 ms per loop
In [308]: timeit M1+M1.T-D
1000 loops, best of 3: 1.11 ms per loop
完成整个事情的另一种方法是利用 coo
允许重复的 i,j
值这一事实,这些值将在转换为 csr
格式时求和。因此,您可以将 M
的 row, col, data
数组与 M.T
的数组堆叠在一起(请参阅 M.transpose
了解它们的构造方式),以及 D
的掩码值。 (或者可以从 M
或 M.T
中删除屏蔽的对角线)
例如:
def MplusMT(M):
msk=M.row!=M.col;
data=np.concatenate([M.data, M.data[msk]])
rows=np.concatenate([M.row, M.col[msk]])
cols=np.concatenate([M.col, M.row[msk]])
MM=sparse.coo_matrix((data, (rows, cols)), shape=M.shape)
return MM
# alt version with a more explicit D
# msk=M.row==M.col;
# data=np.concatenate([M.data, M.data,-M.data[msk]])
MplusMT
写的非常快,因为它只是做数组连接,而不是求和。为此,我们必须将其转换为 csr
矩阵。
MplusMT(M).tocsr()
这需要相当长的时间。在我的有限测试中,这种方法仍然比 M+M.T-D
快 2 倍以上。因此它是构建复杂稀疏矩阵的潜在工具。