适当优化一些计算

时间:2017-05-30 14:03:25

标签: python numpy optimization linear-algebra

尝试使用numpy优化一段代码,我想知道这是否是正确的方法。

这是计算的公式 ,矩阵是低三角形的。

1

这是我的尝试:

(np.sum(P) - np.trace(P)) / np.sum(((t[np.newaxis]).T - t) * P)

这是否可以获得最佳效果,或者您能看到更有效的方式吗?

1 个答案:

答案 0 :(得分:1)

瓶颈似乎是分母的计算,似乎np.einsum应该有帮助,因为我们正在执行逐元素乘法和求和。因此,分母可以这样计算 -

np.einsum('ij,ij',t[:,None]-t, P)

计时和验证 -

In [414]: N = 5000
     ...: P = np.random.rand(N,N)
     ...: t = np.random.rand(N)
     ...: out = (np.sum(P) - np.trace(P)) / np.sum(((t[np.newaxis]).T - t) * P)
     ...: 

# Original method    
In [415]: den1 = np.sum(((t[np.newaxis]).T - t) * P)

# Proposed method    
In [416]: den2 = np.einsum('ij,ij',t[:,None]-t, P)

In [417]: np.allclose(den1, den2)
Out[417]: True

In [419]: %timeit np.sum(((t[np.newaxis]).T - t) *P)
10 loops, best of 3: 86.9 ms per loop

In [420]: %timeit np.einsum('ij,ij',t[:,None]-t, P)
10 loops, best of 3: 49.7 ms per loop

对于分子,似乎大多数运行时花费在np.sum(P)上:

In [422]: %timeit (np.sum(P) - np.trace(P))
100 loops, best of 3: 10.4 ms per loop

In [423]: %timeit np.sum(P)
100 loops, best of 3: 10.4 ms per loop

所以,我们可以保留分子原样。