使用numpy ufuncs vs内置运算符

时间:2013-03-28 18:13:46

标签: python numpy

我很好奇使用numpy ufuncs与内置运算符与内置运算符的'function'版本相比的好处和权衡。

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

有几种方法可以用一个数字'过滤'一个numpy数组来获得一个布尔数组。每个表单给出相同的结果,但是有一个优先的时间/地点使用一个而不是另一个吗?这个例子我将一个数组与一个数字进行比较,因此所有3个都可以工作。

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

>>> x = numpy.arange(0, 10000)
>>> x
array([   0,    1,    2, ..., 9997, 9998, 9999])

'&LT;'操作

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

operator.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

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

请注意,它们都具有相当的性能和完全相同的结果。我猜测所有这些调用实际上最终都在同一个函数中,因为<operator.lt都映射到numpy数组上的__lt__,这可能是使用{{1或者等价的?

那么,哪个更“惯用”和“首选”?

2 个答案:

答案 0 :(得分:3)

在这种情况下,首选表单是x < 5000,因为它更简单,并且您已经在使用numpy数组。

ufunc s意味着允许对任何类型的数据(不仅是numpy数组)进行这些操作

>>> numpy.less([1, 2, 3, 4, 6, 8], 5)
array([ True,  True,  True,  True, False, False], dtype=bool)

>>> [1, 2, 3, 4, 6, 8] < 5
False

在Python 3上,最后一次比较会引发错误。

答案 1 :(得分:3)

一般来说,考虑到“可读性计数”的咒语,实际的操作员应始终是您的首选。使用operator版本有一个位置,当您可以用更紧凑的lambda a, b: a < b替换operator.lt时,但在此之外并不多。并且你真的不应该使用显式调用相应的ufunc,除非你想使用out参数直接将计算值存储在现有数组中。

那就是说,如果你担心的是表现,你应该进行公平的比较,因为正如你所说,你所有的电话最终都是由numpy的less ufunc处理。

如果您的数据已经在一个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

不确定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

请注意,在numpy数组上运行的ufuncs 比上述任何一种更快

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

In [25]: %timeit y < 5000
10000 loops, best of 3: 82.8 us per loop
相关问题