使用 numpy ufunc 与内置运算符

dur*_*2.0 6 python numpy

我很好奇使用 numpy ufuncs与内置运算符与内置运算符的“函数”版本的好处和权衡。

我对所有的 ufunc 很好奇。也许有时候有些比其他的更有用。但是,<为了简单起见,我将在我的示例中使用。

有几种方法可以通过单个数字“过滤” numpy 数组以获得布尔数组。每种形式都给出相同的结果,但是否有一个首选的时间/地点来使用另一种?这个例子我将一个数组与一个数字进行比较,所以所有 3 个都可以工作。

考虑使用以下数组的所有示例:

>>> x = numpy.arange(0, 10000)
>>> x
array([   0,    1,    2, ..., 9997, 9998, 9999])
Run Code Online (Sandbox Code Playgroud)

'<' 运算符

>>> x < 5000
array([ True,  True,  True, ..., False, False, False], dtype=bool)
>>> %timeit x < 5000
100000 loops, best of 3: 15.3 us per loop
Run Code Online (Sandbox Code Playgroud)

运营商.lt

>>> import operator
>>> operator.lt(x, 5000)
array([ True,  True,  True, ..., False, False, False], dtype=bool)
>>> %timeit operator.lt(x, 5000)
100000 loops, best of 3: 15.3 us per loop
Run Code Online (Sandbox Code Playgroud)

numpy.less

>>> numpy.less(x, 5000)
array([ True,  True,  True, ..., False, False, False], dtype=bool)
>>> %timeit numpy.less(x, 5000)
100000 loops, best of 3: 15 us per loop
Run Code Online (Sandbox Code Playgroud)

请注意,它们都实现了几乎相同的性能和完全相同的结果。我猜,所有这些要求实际上在同一个函数结束反正因为<operator.lt这两个地图,__lt__一个numpy的阵列上,这是使用可能实现numpy.less或等值?

那么,哪个更“惯用”和“更喜欢”?

Jai*_*ime 4

一般来说,考虑到“可读性很重要”这一口号,实际操作员应该始终是您的首选。使用operator版本有一个地方,当您可以替换lambda a, b: a < b为更紧凑的版本时operator.lt,但除此之外就没有太多了。而且您确实不应该对相应的 ufunc 进行显式调用,除非您想使用out参数将计算值直接存储在现有数组中。

也就是说,如果您担心的是性能,您应该进行公平的比较,因为正如您所说,您的所有调用最终都由 numpy 的lessufunc 处理。

如果您的数据已经在 numpy 数组中,那么您已经表明它们的性能都相似,因此<为了清楚起见,请使用运算符。

如果您的数据位于 python 对象(例如列表)中怎么办?好吧,这里有一些时间供您思考:

In [13]: x = range(10**5)

In [19]: %timeit [j < 5000 for j in x]
100 loops, best of 3: 5.32 ms per loop

In [20]: %timeit np.less(x, 5000)
100 loops, best of 3: 11.3 ms per loop

In [21]: %timeit [operator.lt(j, 5000) for j in x]
100 loops, best of 3: 16.2 ms per loop
Run Code Online (Sandbox Code Playgroud)

不知道为什么operator.lt这么慢,但你显然想远离它。如果你想从 Python 对象输入获取 numpy 数组作为输出,那么这可能是最快的:

In [22]: %timeit np.fromiter((j < 5000 for j in x), dtype=bool, count=10**5)
100 loops, best of 3: 7.91 ms per loop
Run Code Online (Sandbox Code Playgroud)

请注意,在 numpy 数组上运行的 ufunc比上述任何一个都快得多

In [24]: y = np.array(x)

In [25]: %timeit y < 5000
10000 loops, best of 3: 82.8 us per loop
Run Code Online (Sandbox Code Playgroud)