数字矢量化:为什么这么慢?

2024-04-19 07:30:46 发布

您现在位置:Python中文网/ 问答频道 /正文

expit函数,在西皮。特别,是一个矢量化的sigmoid函数。它计算1/(1+e^(-x)),这很复杂,可能涉及泰勒级数。在

我了解了“快速sigmoid”,1/(1+abs(x)),它应该快得多——但是内置表达式函数的性能远远超过它,即使我把它作为lambda表达式交给数字矢量化. 在

有一种方法可以测试它们:

from scipy.special import expit
data = np.random.rand(1000000)

内置复杂的乙状结肠速度很快:

^{pr2}$

较简单的乙状结肠大约慢20倍:

%prun np.vectorize( lambda x: (x / (1 + abs(x)) + 1) / 2 )(data)

2000023 function calls in 1.992 seconds

Ordered by: internal time

 ncalls  tottime  percall  cumtime  percall filename:lineno(function)
1000001    1.123    0.000    1.294    0.000 <string>:1(<lambda>)
      1    0.558    0.558    1.950    1.950 function_base.py:2276(_vectorize_call)
1000001    0.170    0.000    0.170    0.000 {built-in method builtins.abs}
      4    0.098    0.025    0.098    0.025 {built-in method numpy.core.multiarray.array}
      1    0.041    0.041    1.991    1.991 function_base.py:2190(__call__)
      1    0.000    0.000    0.068    0.068 function_base.py:2284(<listcomp>)
      1    0.000    0.000    1.992    1.992 {built-in method builtins.exec}
      1    0.000    0.000    1.991    1.991 <string>:1(<module>)
      1    0.000    0.000    0.000    0.000 function_base.py:2220(_get_ufunc_and_otypes)
      1    0.000    0.000    0.000    0.000 function_base.py:2162(__init__)
      1    0.000    0.000    0.000    0.000 function_base.py:2242(<listcomp>)
      2    0.000    0.000    0.000    0.000 numeric.py:414(asarray)
      1    0.000    0.000    0.000    0.000 {built-in method numpy.core.umath.frompyfunc}
      1    0.000    0.000    0.000    0.000 function_base.py:2266(<listcomp>)
      2    0.000    0.000    0.000    0.000 {built-in method builtins.isinstance}
      1    0.000    0.000    0.000    0.000 {built-in method builtins.len}
      1    0.000    0.000    0.000    0.000 {method 'join' of 'str' objects}
      1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

Tags: lambda函数inpybasefunctionabs矢量化
1条回答
网友
1楼 · 发布于 2024-04-19 07:30:46

为什么numpy.vectorize速度慢的问题以前几乎肯定有人问过,但在一次简短的搜索中,我没有发现一个明显使这个问题重复的问题。为了回答这个问题,我只引用vectorize docstring:“提供向量化函数主要是为了方便,而不是为了性能。该实现实际上是一个for循环。”

你想让1/(1 + abs(x))快一点。numpy有一个名为numpy.abs(也称为^{}它们是同一对象的不同名称)。它计算其参数中每个元素的绝对值,并且在C代码中这样做,所以速度很快。另外,Python内置函数abs知道如何将参数分配给具有方法__abs__(numpy数组就是这样)的对象,因此您还可以使用Python的abs()计算numpy数组的元素级绝对值。在下面,我将使用np.abs。在

下面是np.abs的用法示例:

In [25]: x = np.array([-2, -1.5, 0, 5, 10])

In [26]: np.abs(x)
Out[26]: array([  2. ,   1.5,   0. ,   5. ,  10. ])

以下是scipy.special.expit和{}对于大数组x的性能比较:

^{pr2}$

所以1.0/(1 + np.abs(x))expit(x)快很多。在

相关问题 更多 >