python - 根据条件创建新的 numpy 数组

标签 python performance numpy vectorization

我有 2 个 numpy 数组:

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

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

最佳答案

关注性能并使用两种方法可以添加一些方法。一种方法是获取有效值的 bool 数组并使用 .astype() method 转换为 int 数据类型。 .另一种方法可能涉及使用 np.where这让我们可以根据相同的 bool 数组在 01 之间进行选择。因此,基本上我们会有两种方法,一种利用有效的数据类型转换,另一种使用选择标准。现在,可以通过两种方式获得 bool 数组——一种使用简单比较,另一种使用 np.logical_and。 .因此,通过两种获取 bool 数组的方法和两种将 bool 数组转换为 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

关于python - 根据条件创建新的 numpy 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38943403/

相关文章:

python - 比较 numpy 数组中的整行和整列并删除选定的行和列

python - SWIG:需要可变字符串类型映射帮助

python - islice 一次读取 N 行的问题

python - Selenium:理解等待

java - 在 Java 中有效地读取 zip 文件

performance - 找到二维三角形中任意点的最快方法

python - 提取 numpy 结构化数组的最高值

python - 如何将tensorflow placerholder变量转换为numpy数组?

python - 如何在 HP Prime 图形计算器上运行 Python?

具有水平和垂直滚动条的 python Tkinter 框架