我正在尝试Numba来加速一个计算联合发生的最小条件概率的函数。在
import numpy as np
from numba import double
from numba.decorators import jit, autojit
X = np.random.random((100,2))
def cooccurance_probability(X):
P = X.shape[1]
CS = np.sum(X, axis=0) #Column Sums
D = np.empty((P, P), dtype=np.float) #Return Matrix
for i in range(P):
for j in range(P):
D[i, j] = (X[:,i] * X[:,j]).sum() / max(CS[i], CS[j])
return D
cooccurance_probability_numba = autojit(cooccurance_probability)
然而,我发现cooccurance_probability
和{
为什么会这样?可能是因为逐元素操作造成的吗?在
我举个例子: http://nbviewer.ipython.org/github/ellisonbg/talk-sicm2-2013/blob/master/NumbaCython.ipynb
[注意:由于问题的对称性,我可以将执行时间缩短一半-但这不是我主要关心的问题]
下面是一个使用乔希的建议的解决方案,这是正确的。但是,max()在下面的实现中工作得很好。如果有一个“safe”python/numpy函数的列表,那就太好了。在
注:我将原始矩阵的维数降为100 x 200]
^{pr2}$%timeit
结果:结果中有趣的一点是,python显式编写的版本执行速度非常慢,因为类型检查开销很大。但是通过麻木工厂是有魔力的。(Numba比使用Numpy的python解决方案快11.5倍)。在
更新:添加了一个Cython函数进行比较(感谢moarningsun:Cython function with variable sized matrix input)
%timeit
结果:我的猜测是,由于对
sum
的调用而不是生成本机代码,这意味着Numba不会显著加快速度。它只是不知道如何优化/翻译sum
(此时)。此外,通常最好使用Numba将矢量化操作展开为显式循环。请注意,您链接到的ipynb只调用np.sqrt
,我相信它确实被翻译成了机器代码,它对元素而不是切片进行操作。我将尝试将内部循环中的和展开为元素上显式的附加循环,而不是采取切片和使用sum
方法。在我的经验是,Numba有时可以创造奇迹,但它不会加快任意python代码的速度。您需要了解它的局限性以及它可以有效地优化什么。还要注意,v0.11在这方面与0.12和0.13有点不同,这是因为Numba在这些版本之间进行了重大的重构。在
相关问题 更多 >
编程相关推荐