最近我在观看一些SciPy2017会议的视频,偶然发现关于Numba的来历--讲述了那些C++的高手们因为对Gil Forsyth和Lorena Barba失去信心而编写的一个库。虽然本人觉得这个做法有些不妥,但我真的很喜欢他们所分享的知识。因为我发现自己正在受益于这个库,并且从Python代码中获得了令人难以置信的表现,所以我觉得应该要写一些关于Numba库的介绍性文章,也可能会在将来添加一系列小的更多类似教程的文章。
1.那么到底什么是Numba?
Numba是一个库,可以在运行时将Python代码编译为本地机器指令,而不会强制大幅度的改变普通的Python代码(稍后再做说明)。翻译/魔术是使用LLVM编译器完成的,该编译器是相当活跃的开源社区开发的。
Numba最初是由Continuum Analytics内部开发,此公司也开发了著名的Anaconda,但现在它是开源的。核心应用领域是math-heavy(密集数学?重型数学?)和array-oriented(面向数组)的功能,它们在本地Python中相当缓慢。想象一下,在Python中编写一个模块,必须一个元素接着一个元素的循环遍历一个非常大的数组来执行一些计算,而不能使用向量操作来重写。这是很不好的主意,是吧?所以“通常”这类库函数是用C / C ++或Fortran编写的,编译后,在Python中作为外部库使用。Numba这类函数也可以写在普通的Python模块中,而且运行速度的差别正在逐渐缩小。
2.怎么才能get到Numba呢?
安装Numba的推荐方法是使用conda包管理
conda install numba
你也可以用pip来安装Numba,但是最新版本的发布才一天之久。但是,只要你能够使用conda,我会推荐使用它,因为它能够为你安装例如CUDA工具包,也许你想让你的Python代码GPU就绪(当然,这也是有可能的!)。
3.如何使用Numba呢?
使用它的要求不多。基本上,你写一个自己的“普通”的Python函数,然后给函数定义添加一个装饰(如果你不是很熟悉装饰器,读一下关于this或that)。你可以使用不同类型的装饰器,但@jit可能是刚开始的选择之一。其他装饰器可用于例如创建numpy通用功能@vectorize或编写将在CUDA GPU上执行的代码@cuda。我不会在这篇文章中介绍这些装饰。现在,让我们来看看基本的步骤。他们提供的代码示例是2d数组的求和函数,以下是代码:
from numba import jit
from numpy import arange
# jit decorator tells Numba to compile this function.# The argument types will be inferred by Numba when function is called.
@jit
def sum2d(arr):
M, N = arr.shape
result = 0.0
for i in range(M):
for j in range(N):
result += arr[i,j]
return result
a = arange(9).reshape(3,3)
print(sum2d(a))
正如你所看到的,Numba装饰器被添加到函数定义中,并且voilá这个函数将运行得很快。但是,这里带来了很有趣的注意事项:你只能使用Numpy和标准库里的函数来加快Numba速度,甚至不需要开了他们所有的特性。他们有一个相当好的文档(参考资料),列出了所有支持的内容。见here是所支持Python的功能和here 是所支持的Numpy功能。现在支持的功能可能还不太多,但我想告诉你,这就够了!请记住,Numba不是要加快你的数据库查询或如何强化图像处理功能。他们的目标是加快面向数组的计算,我们可以使用它们库中提供的函数来解决。





































苏公安网备 32011402010933号