我正在寻找一种快速计算方法:
import numpy as np
a = np.array([-1,1,2,-4,5.5,-0.1,0])
现在我想将a
转换为二进制值数组,使得a
的每个正条目都为1,否则为0。所以我想要的结果是:
array([ 0., 1., 1., 0., 1., 0., 0.])
实现这一目标的一种方法是
np.array([x if x >=0 else 0 for x in np.sign(a)])
array([ 0., 1., 1., 0., 1., 0., 0.])
但我希望有人可以指出更快的解决方案。
%timeit np.array([x if x >=0 else 0 for x in np.sign(a)])
100000 loops, best of 3: 11.4 us per loop
编辑:为答案提供优秀的解决方案
%timeit (a > 0).astype(int)
100000 loops, best of 3: 3.47 us per loop
答案 0 :(得分:3)
您可以检查a
大于0的位置,并将布尔数组转换为整数数组:
>>> (a > 0).astype(int)
array([0, 1, 1, 0, 1, 0, 0])
这应该明显快于问题中提出的方法(特别是在较大的数组上),因为它避免了在Python级别对数组进行循环。
更快的是简单地将布尔数组视为int8
dtype - 这可以防止需要从布尔数组创建新数组:
>>> (a > 0).view(np.int8)
array([0, 1, 1, 0, 1, 0, 0], dtype=int8)
时序:
>>> b = np.random.rand(1000000)
>>> %timeit np.array([ x if x >=0 else 0 for x in np.sign(b)])
1 loops, best of 3: 420 ms per loop
>>> %timeit (b > 0).astype(int)
100 loops, best of 3: 4.63 ms per loop
>>> %timeit (b > 0).view(np.int8)
1000 loops, best of 3: 1.12 ms per loop
答案 1 :(得分:3)
你可以使用mask:
来做到这一点 (a > 0).astype(int)
我不知道如何正确使用timeit,甚至
import numpy as np
from datetime import datetime
n = 50000000
a = np.random.rand(1, n).ravel()
startTime = datetime.now()
np.array([ x if x >=0 else 0 for x in np.sign(a)])
print datetime.now() - startTime
startTime = datetime.now()
(a > 0).astype(int)
print datetime.now() - startTime
pass
显示 26秒与 0.5秒的显着差异。
根据您的评论P.S。
我会计算距离,比如汉明
你真的不需要一个整数数组,而a > 0
就足够了。它可以节省你的记忆力,让事情变得更快。