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}
为什么
numpy.vectorize
速度慢的问题以前几乎肯定有人问过,但在一次简短的搜索中,我没有发现一个明显使这个问题重复的问题。为了回答这个问题,我只引用vectorize docstring:“提供向量化函数主要是为了方便,而不是为了性能。该实现实际上是一个for循环。”你想让} 它们是同一对象的不同名称)。它计算其参数中每个元素的绝对值,并且在C代码中这样做,所以速度很快。另外,Python内置函数
1/(1 + abs(x))
快一点。numpy有一个名为numpy.abs
(也称为^{abs
知道如何将参数分配给具有方法__abs__
(numpy数组就是这样)的对象,因此您还可以使用Python的abs()
计算numpy数组的元素级绝对值。在下面,我将使用np.abs
。在下面是
np.abs
的用法示例:以下是}对于大数组
^{pr2}$scipy.special.expit
和{x
的性能比较:所以
1.0/(1 + np.abs(x))
比expit(x)
快很多。在相关问题 更多 >
编程相关推荐