分数计算时间过长:避免循环-python
我是python新手,需要您的帮助 我有三个矩阵,尤其是:分数计算时间过长:避免循环-python,python,for-loop,optimization,product,sparse-matrix,Python,For Loop,Optimization,Product,Sparse Matrix,我是python新手,需要您的帮助 我有三个矩阵,尤其是: 矩阵M(矩阵的类别:scipy.sparse.csc.csc_矩阵),维数:nxc 矩阵G(矩阵的类别:numpy.ndarray),维数:CxT 矩阵L(矩阵的类别:numpy.ndarray),维数:T×N 式中:N=10000,C=1000,T=20 我想计算一下,这个分数: 我尝试对循环使用两个,一个用于I-索引,另一个用于c。此外,我使用了一个点积来获得等式中的最后一个和。但是我的实现需要太多的时间才能给出结果 这就是我
- 矩阵M(矩阵的类别:scipy.sparse.csc.csc_矩阵),维数:nxc李>
- 矩阵G(矩阵的类别:numpy.ndarray),维数:CxT李>
- 矩阵L(矩阵的类别:numpy.ndarray),维数:T×N
循环使用两个,一个用于I
-索引,另一个用于c
。此外,我使用了一个点
积来获得等式中的最后一个和。但是我的实现需要太多的时间才能给出结果
这就是我实现的:
score = 0.0
for i in range(N):
for c in range(C):
Mic = M[i,c]
score += np.outer(Mic,(np.dot(L[:,i],G[c,:])))
有没有办法避免两个for
循环
提前谢谢你
最佳试试这个score=np.einsum(“ic,ti,ct->”,M,L,G)
EDIT1
顺便说一下,在您的例子中,score=np.sum(np.diag(M@G@L))
(在从3.5版开始的PYTHON3中,您可以为matmul
函数使用@
操作符的语义)比einsum
更快(尤其是在np.trace((L@M)@G)中)
由于高效使用内存,也许@hpaulj在他的评论中是这样说的)。但是einsum
更容易用于复杂的张量积(使用einsum
编码,我直接使用了你的数学表达式,没有考虑优化)
通常,将for
与numpy
一起使用会导致计算速度大幅降低(在numpy
的情况下,请考虑“矢量化计算”)。我并不感到惊讶。在numpy
数组上这样的迭代速度很慢,而在稀疏数组上的迭代速度更慢csc
矩阵针对矩阵乘法(dot)
进行了优化,甚至需要很大程度的稀疏性(相对于总形状,只有少数非零值)。当Mic
是标量值(可能是0)时,为什么要使用outer
G@L
应给出一个(C,N)形数组。我打算建议M.dot(G@L)
,但这是(N,N),而您需要它的对角线,或者更确切地说是它的轨迹。我将尝试此解决方案!谢谢我认为einsum
与M
不起作用。使用M.A
是的,如果内存足够。我的笔记本电脑上有8GB的RAM,没有内存问题(所有M、L、G都有浮点64)。非常感谢!如果我还想在最后一次求和的结果上应用一个日志(即点积的日志),有没有办法继续使用einsum
?提前谢谢你!这应该是可行的:score=np.sum(np.diag(M@np.log(G@L)))对于sum\c M\u ic*log(sum\u t L\u ti*G\u ct))
,使用einsum
不是一个好的解决方案(直接遵循您的表达式:np.einsum(“ic,ci->”,M,np.log(np.einsum(“ti,ct ci,L,G))
)。你有一个很好的解决办法。一个注释:np.sum(np.diag(A))
对于方阵A
与np.trace(A)
相同。