NumPy的数学函数是否比Python快?

Mer*_*moz 58 python performance numpy

我有一个由基本数学函数(abs,cosh,sinh,exp,...)组合定义的函数.

我想知道它是否有所作为(速度)使用,例如, numpy.abs()而不是abs()

Eri*_*got 77

以下是时间结果:

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

(PS:'[abs(x) for x in a]'在Python 2.7中比在更好的情况下更慢,map(abs, a)大约快30% - 这仍然比NumPy慢得多.)

因此,numpy.abs()对于1000个元素而言,与单个浮点数相比,不需要花费更多的时间!

  • @tbhartman:注意`times`的`-s`选项:`import numpy`实际上只在*setup*期间***完成.它没有定时.至于`abs()`示例,用`x`替换`abs(x)`表示`abs()`使用总运行时间的一半.在任何情况下,重点都保持不变:与纯(CPython解释)Python相比,NumPy非常快. (12认同)
  • 很高兴得到python -m timeit -s'import numpy'-s'a = numpy.array((1,)*1000)''numpy.abs(a)'的结果,以显示numpy如何快速与它的阵列 (5认同)
  • @EOL:你的timeit似乎包括导入numpy,单独需要几秒钟.此外,在你的第二个例子中,我想知道Python的基本"abs"函数的大部分时间是否来自你的列表理解而不是来自"abs"函数本身? (5认同)

Bat*_*hyX 25

你应该使用numpy函数来处理numpy的类型,并使用常规的python函数来处理常规的python类型.

由于类型转换,在将python内置函数与numpy混合时通常会出现性能最差的情况.这些类型转换最近已经过优化,但最好不要使用它们.当然,您的里程可能会有所不同,因此请使用分析工具来确定.

如果您想进一步优化您的程序,还可以考虑使用cython等程序或制作C模块.或者考虑在表演很重要时不要使用python.

但是,当你的数据被放入一个numpy数组时,numpy可以非常快速地计算一堆数据.


col*_*ang 5

事实上,在numpy数组上

内置abs调用numpy的实现__abs__,请参阅为什么像abs这样的内置函数适用于numpy数组?

因此,理论上应该没有太多的性能差异.

import timeit

x = np.random.standard_normal(10000)

def pure_abs():
    return abs(x)

def numpy_abs():
    return np.absolute(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
Run Code Online (Sandbox Code Playgroud)