根据条件创建新的numpy数组

时间:2016-08-14 14:54:37

标签: python performance numpy vectorization

我有2个numpy数组:

aa = np.random.rand(5,5)
bb = np.random.rand(5,5)

当aa和bb都超过0.5时,如何创建一个值为1的新数组?

3 个答案:

答案 0 :(得分:8)

关注性能并使用两种方法可以添加一些方法。一种方法是获取有效的布尔数组并使用.astype() method转换为int数据类型。另一种方法可能涉及使用np.where,它允许我们根据相同的布尔数组在01之间进行选择。因此,基本上我们有两种方法,一种利用有效的数据类型转换,另一种利用选择标准。现在,布尔数组可以通过两种方式获得 - 一种使用简单比较,另一种使用np.logical_and。因此,有两种获取布尔数组的方法和两种将布尔数组转换为int数组的方法,我们最终将得到四种实现,如下所示 -

out1 = ((aa>0.5) & (bb>0.5)).astype(int)
out2 = np.logical_and(aa>0.5, bb>0.5).astype(int)
out3 = np.where((aa>0.5) & (bb>0.5),1,0)
out4 = np.where(np.logical_and(aa>0.5, bb>0.5), 1, 0)

您可以使用数据类型来使用精度较低的类型,这不应该因为我们将值设置为01而受到影响。这种优势应该是明显的加速,因为它利用了内存效率。我们可以使用int8, uint8, np.int8, np.uint8 types。因此,使用新int数据类型的前面列出的方法的变体将是 -

out5 = ((aa>0.5) & (bb>0.5)).astype('int8')
out6 = np.logical_and(aa>0.5, bb>0.5).astype('int8')
out7 = ((aa>0.5) & (bb>0.5)).astype('uint8')
out8 = np.logical_and(aa>0.5, bb>0.5).astype('uint8')

out9 = ((aa>0.5) & (bb>0.5)).astype(np.int8)
out10 = np.logical_and(aa>0.5, bb>0.5).astype(np.int8)
out11 = ((aa>0.5) & (bb>0.5)).astype(np.uint8)
out12 = np.logical_and(aa>0.5, bb>0.5).astype(np.uint8)

运行时测试(因为我们专注于这篇文章的表现) -

In [17]: # Input arrays
    ...: aa = np.random.rand(1000,1000)
    ...: bb = np.random.rand(1000,1000)
    ...: 

In [18]: %timeit ((aa>0.5) & (bb>0.5)).astype(int)
    ...: %timeit np.logical_and(aa>0.5, bb>0.5).astype(int)
    ...: %timeit np.where((aa>0.5) & (bb>0.5),1,0)
    ...: %timeit np.where(np.logical_and(aa>0.5, bb>0.5), 1, 0)
    ...: 
100 loops, best of 3: 9.13 ms per loop
100 loops, best of 3: 9.16 ms per loop
100 loops, best of 3: 10.4 ms per loop
100 loops, best of 3: 10.4 ms per loop

In [19]: %timeit ((aa>0.5) & (bb>0.5)).astype('int8')
    ...: %timeit np.logical_and(aa>0.5, bb>0.5).astype('int8')
    ...: %timeit ((aa>0.5) & (bb>0.5)).astype('uint8')
    ...: %timeit np.logical_and(aa>0.5, bb>0.5).astype('uint8')
    ...: 
    ...: %timeit ((aa>0.5) & (bb>0.5)).astype(np.int8)
    ...: %timeit np.logical_and(aa>0.5, bb>0.5).astype(np.int8)
    ...: %timeit ((aa>0.5) & (bb>0.5)).astype(np.uint8)
    ...: %timeit np.logical_and(aa>0.5, bb>0.5).astype(np.uint8)
    ...: 
100 loops, best of 3: 5.6 ms per loop
100 loops, best of 3: 5.61 ms per loop
100 loops, best of 3: 5.63 ms per loop
100 loops, best of 3: 5.63 ms per loop
100 loops, best of 3: 5.62 ms per loop
100 loops, best of 3: 5.62 ms per loop
100 loops, best of 3: 5.62 ms per loop
100 loops, best of 3: 5.61 ms per loop

In [20]: %timeit 1 * ((aa > 0.5) & (bb > 0.5)) #@BPL's vectorized soln
100 loops, best of 3: 10.2 ms per loop

答案 1 :(得分:3)

这个怎么样?

import numpy as np

aa = np.random.rand(5, 5)
bb = np.random.rand(5, 5)

print aa
print bb

cc = 1 * ((aa > 0.5) & (bb > 0.5))
print cc

答案 2 :(得分:-3)

当索引i处的aa和bb的元素超过0.5时,则为新数组 在索引i有1个

aa = np.random.rand(5,5)
bb = np.random.rand(5,5)
new_arr = []
for i in range(5):
    for j in range(5):
        if aa[i] >0.5 and bb[i]>0.5:
              new_arr[i] = 1
        else:
              new_arr[i] = "any Value You want