分数计算时间太长:避免循环 - python
score calculation takes too long: avoid for loops - python
我是python的新手,需要您的帮助。
我有三个矩阵,特别是:
- 矩阵M(class的矩阵:scipy.sparse.csc.csc_matrix),维度:N x C;
- 矩阵G(矩阵的class:numpy.ndarray),维度:C x T;
- 矩阵L(矩阵的class:numpy.ndarray),尺寸:T x N.
其中:N = 10000,C = 1000,T = 20。
我要计算,这个分数:
![\sum_{i=1}^{N}(\sum_{c=1}^{C}M_{i,c}\cdot \sum_{t=1}^{T} L_{t,i}\cdot G_{c,t})](https://latex.codecogs.com/gif.latex?%5Csum_%7Bi=1%7D%5E%7BN%7D(%5Csum_%7Bc=1%7D%5E%7BC%7DM_%7Bi,c%7D%5Ccdot&space;%5Csum_%7Bt=1%7D%5E%7BT%7D&space;L_%7Bt,i%7D%5Ccdot&space;G_%7Bc,t%7D))
我尝试使用两个 for
循环,一个用于 i
-索引,一个用于 c
。此外,我使用 dot
乘积来获得等式中的最后一个和。但是我的实现需要太多的时间才能给出结果。
这是我实现的:
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))
(在 PYTHON3 从版本 3.5 开始,你可以使用 @
运算符的语义来实现 matmul
函数) 比 einsum
快(特别是在 np.trace((L @ M) @ G )
中,由于内存的有效使用,也许@hpaulj 在他的评论中就是这个意思)。但是 einsum
更容易用于复杂的张量积(用 einsum
编码我没有考虑优化直接使用你的数学表达式)。
通常,将 for
与 numpy
一起使用会导致计算速度急剧下降(想想 numpy
情况下的“向量化计算”)。
我是python的新手,需要您的帮助。
我有三个矩阵,特别是:
- 矩阵M(class的矩阵:scipy.sparse.csc.csc_matrix),维度:N x C;
- 矩阵G(矩阵的class:numpy.ndarray),维度:C x T;
- 矩阵L(矩阵的class:numpy.ndarray),尺寸:T x N.
其中:N = 10000,C = 1000,T = 20。
我要计算,这个分数:
我尝试使用两个 for
循环,一个用于 i
-索引,一个用于 c
。此外,我使用 dot
乘积来获得等式中的最后一个和。但是我的实现需要太多的时间才能给出结果。
这是我实现的:
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))
(在 PYTHON3 从版本 3.5 开始,你可以使用 @
运算符的语义来实现 matmul
函数) 比 einsum
快(特别是在 np.trace((L @ M) @ G )
中,由于内存的有效使用,也许@hpaulj 在他的评论中就是这个意思)。但是 einsum
更容易用于复杂的张量积(用 einsum
编码我没有考虑优化直接使用你的数学表达式)。
通常,将 for
与 numpy
一起使用会导致计算速度急剧下降(想想 numpy
情况下的“向量化计算”)。