NumPy的数学函数比Python的快吗?
我有一个函数,它是由一些基本的数学函数组合而成的,比如绝对值函数(abs)、双曲余弦函数(cosh)、双曲正弦函数(sinh)、指数函数(exp)等等。
我在想,使用 numpy.abs()
这个函数和直接使用 abs()
这个内置函数,速度上会有什么区别吗?
3 个回答
9
实际上,在numpy数组上,
内置的 abs
函数是通过 __abs__
来调用numpy的实现,具体可以参考这个链接:为什么像abs这样的内置函数可以在numpy数组上使用?
所以,从理论上讲,性能差别不应该太大。
import timeit
x = np.random.standard_normal(10000)
def pure_abs():
return abs(x)
def numpy_abs():
return np.abs(x)
n = 10000
t1 = timeit.timeit(pure_abs, number = n)
print('Pure Python abs:', t1)
t2 = timeit.timeit(numpy_abs, number = n)
print('Numpy abs:', t2)
Pure Python abs: 0.435754060745
Numpy abs: 0.426516056061
25
你应该用numpy的函数来处理numpy的数据类型,而用普通的python函数来处理普通的python数据类型。
当你把python的内置函数和numpy混在一起用时,通常会导致性能下降,因为需要进行类型转换。虽然这些类型转换最近有了一些优化,但通常还是不建议这样做。当然,具体情况可能不同,所以最好使用一些性能分析工具来检查一下。
如果你想进一步优化你的程序,可以考虑使用像cython这样的工具,或者自己写一个C语言模块。如果性能很重要,可能还要考虑不使用python。
不过,一旦你的数据放进了numpy数组,numpy在处理大量数据时会非常快。
88
这里是一些时间测试的结果:
lebigot@weinberg ~ % python -m timeit 'abs(3.15)'
10000000 loops, best of 3: 0.146 usec per loop
lebigot@weinberg ~ % python -m timeit -s 'from numpy import abs as nabs' 'nabs(3.15)'
100000 loops, best of 3: 3.92 usec per loop
numpy.abs()
比 abs()
慢,因为它还要处理 Numpy 数组:这意味着它有额外的代码来提供这种灵活性。
不过,Numpy 在处理数组时确实很快:
lebigot@weinberg ~ % python -m timeit -s 'a = [3.15]*1000' '[abs(x) for x in a]'
10000 loops, best of 3: 186 usec per loop
lebigot@weinberg ~ % python -m timeit -s 'import numpy; a = numpy.empty(1000); a.fill(3.15)' 'numpy.abs(a)'
100000 loops, best of 3: 6.47 usec per loop
(顺便说一下,'[abs(x) for x in a]'
在 Python 2.7 中比更好的 map(abs, a)
慢,大约慢 30%,而 map
还是比 Numpy 慢得多。)
所以,numpy.abs()
处理 1000 个元素所花的时间并不会比处理 1 个浮点数多多少!