分数计算时间过长:避免循环-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。此外,我使用了一个点积来获得等式中的最后一个和。但是我的实现需要太多的时间才能给出结果 这就是我

我是python新手,需要您的帮助

我有三个矩阵,尤其是:

  • 矩阵M(矩阵的类别:scipy.sparse.csc.csc_矩阵),维数:nxc
  • 矩阵G(矩阵的类别:numpy.ndarray),维数:CxT
  • 矩阵L(矩阵的类别:numpy.ndarray),维数:T×N
式中:N=10000,C=1000,T=20

我想计算一下,这个分数:

我尝试对
循环使用两个
,一个用于
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)
相同。