gpt4 book ai didi

python - 有效地累积稀疏 scipy 矩阵的集合

转载 作者:太空狗 更新时间:2023-10-29 21:40:37 24 4
gpt4 key购买 nike

我有一个 O(N) NxN scipy.sparse.csr_matrix 的集合,每个稀疏矩阵都有 N 个元素集的顺序。我想将所有这些矩阵加在一起以获得一个常规的 NxN numpy 数组。 (N 大约为 1000)。矩阵中非零元素的排列使得结果总和肯定不是稀疏的(实际上几乎没有零元素)。

目前我正在做

reduce(lambda x,y: x+y,[m.toarray() for m in my_sparse_matrices])

虽然有效,但速度有点慢:当然,那里正在进行的大量无意义的零处理绝对是可怕的。

还有更好的办法吗?在 docs 中对我来说没有什么明显的.

更新:根据 user545424 的建议,我尝试了对稀疏矩阵求和以及将稀疏矩阵求和到稠密矩阵的替代方案。下面的代码显示了在可比时间运行的所有方法(Python 2.6.6 on amd64 Debian/Squeeze on a quad-core i7)

import numpy as np
import numpy.random
import scipy
import scipy.sparse
import time

N=768
S=768
D=3

def mkrandomsparse():
m=np.zeros((S,S),dtype=np.float32)
r=np.random.random_integers(0,S-1,D*S)
c=np.random.random_integers(0,S-1,D*S)
for e in zip(r,c):
m[e[0],e[1]]=1.0
return scipy.sparse.csr_matrix(m)

M=[mkrandomsparse() for i in xrange(N)]

def plus_dense():
return reduce(lambda x,y: x+y,[m.toarray() for m in M])

def plus_sparse():
return reduce(lambda x,y: x+y,M).toarray()

def sum_dense():
return sum([m.toarray() for m in M])

def sum_sparse():
return sum(M[1:],M[0]).toarray()

def sum_combo(): # Sum the sparse matrices 'onto' a dense matrix?
return sum(M,np.zeros((S,S),dtype=np.float32))

def benchmark(fn):
t0=time.time()
fn()
t1=time.time()
print "{0:16}: {1:.3f}s".format(fn.__name__,t1-t0)

for i in xrange(4):
benchmark(plus_dense)
benchmark(plus_sparse)
benchmark(sum_dense)
benchmark(sum_sparse)
benchmark(sum_combo)
print

然后退出

plus_dense      :  1.368s
plus_sparse : 1.405s
sum_dense : 1.368s
sum_sparse : 1.406s
sum_combo : 1.039s

虽然您可以通过扰乱 N、S、D 参数来获得一种或另一种方法的结果领先 2 倍左右……但是没有什么比您希望从中看到的数量级改进更好的了考虑到零添加的数量,应该可以跳过。

最佳答案

如果您的矩阵非常稀疏,我想我已经找到了将其速度提高约 10 倍的方法。

In [1]: from scipy.sparse import csr_matrix

In [2]: def sum_sparse(m):
...: x = np.zeros(m[0].shape)
...: for a in m:
...: ri = np.repeat(np.arange(a.shape[0]),np.diff(a.indptr))
...: x[ri,a.indices] += a.data
...: return x
...:

In [6]: m = [np.zeros((100,100)) for i in range(1000)]

In [7]: for x in m:
...: x.ravel()[np.random.randint(0,x.size,10)] = 1.0
...:

m = [csr_matrix(x) for x in m]

In [17]: (sum(m[1:],m[0]).todense() == sum_sparse(m)).all()
Out[17]: True

In [18]: %timeit sum(m[1:],m[0]).todense()
10 loops, best of 3: 145 ms per loop

In [19]: %timeit sum_sparse(m)
100 loops, best of 3: 18.5 ms per loop

关于python - 有效地累积稀疏 scipy 矩阵的集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11254248/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com