我已经比较了几种可能的方法,包括熊猫,几种numpy方法和列表理解方法。
首先,让我们从基线开始:
>>> import numpy as np
>>> import operator
>>> import pandas as pd
>>> x = [1, 2, 1, 2]
>>> %time count = np.sum(np.equal(1, x))
>>> print("Count {} using numpy equal with ints".format(count))
CPU times: user 52 µs, sys: 0 ns, total: 52 µs
Wall time: 56 µs
Count 2 using numpy equal with ints
因此,我们的基准是该计数应该正确2
,并且我们应该大约50 us
。
现在,我们尝试使用朴素的方法:
>>> x = ['s', 'b', 's', 'b']
>>> %time count = np.sum(np.equal('s', x))
>>> print("Count {} using numpy equal".format(count))
CPU times: user 145 µs, sys: 24 µs, total: 169 µs
Wall time: 158 µs
Count NotImplemented using numpy equal
/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/ipykernel_launcher.py:1: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison
"""Entry point for launching an IPython kernel.
在这里,我们得到了错误的答案(NotImplemented != 2
),这花了我们很长时间,并且引发了警告。
因此,我们将尝试另一种幼稚的方法:
>>> %time count = np.sum(x == 's')
>>> print("Count {} using ==".format(count))
CPU times: user 46 µs, sys: 1 µs, total: 47 µs
Wall time: 50.1 µs
Count 0 using ==
同样,错误答案(0 != 2
)。这更加隐蔽,因为没有后续警告(0
可以像一样传递2
)。
现在,让我们尝试一个列表理解:
>>> %time count = np.sum([operator.eq(_x, 's') for _x in x])
>>> print("Count {} using list comprehension".format(count))
CPU times: user 55 µs, sys: 1 µs, total: 56 µs
Wall time: 60.3 µs
Count 2 using list comprehension
我们在这里得到正确的答案,而且速度很快!
另一种可能性pandas
:
>>> y = pd.Series(x)
>>> %time count = np.sum(y == 's')
>>> print("Count {} using pandas ==".format(count))
CPU times: user 453 µs, sys: 31 µs, total: 484 µs
Wall time: 463 µs
Count 2 using pandas ==
慢,但是正确!
最后,我将使用的选项是:将numpy
数组转换为object
类型:
>>> x = np.array(['s', 'b', 's', 'b']).astype(object)
>>> %time count = np.sum(np.equal('s', x))
>>> print("Count {} using numpy equal".format(count))
CPU times: user 50 µs, sys: 1 µs, total: 51 µs
Wall time: 55.1 µs
Count 2 using numpy equal
快速正确!
thing
(可能是或不是numpy类型;我不知道),并且想查看是否thing == 'some string'
有简单bool
结果,该怎么办?np.atleast_1d(thing)[0] == 'some string'
?但是,这对于某些小丑把'some string'
数组的第一个元素放进去并不是很可靠。我想我必须先测试类型,thing
然后才==
测试它是否是字符串(或不是numpy对象)。