在NumPy中矢量化循环

Gre*_*reg 5 python arrays numpy vectorization

我正在尝试使用NumPy对循环迭代进行矢量化,但我正在努力实现所需的结果.我有一个像素值数组,所以3维,比如说(512,512,3)并且需要迭代每个x,y并使用第三维中的特定索引计算另一个值.标准循环中此代码的示例如下:

for i in xrange(width):
    for j in xrange(height):
        temp = math.sqrt((scalar1-array[j,i,1])**2+(scalar2-array[j,i,2])**2)
Run Code Online (Sandbox Code Playgroud)

我目前正在做的是:

temp = np.sqrt((scalar1-array[:,:,1])**2+(scalar2-array[:,:,2])**2)
Run Code Online (Sandbox Code Playgroud)

我从中获得的临时数组是所需的维度(x,y),但是一些值与循环实现不同.如何消除循环以在NumPy中有效地计算此示例?

提前致谢!

编辑:

这里的代码给出了temp和temp2的不同结果,显然temp2只是一个单元格的计算

temp = np.sqrt((cb_key-fg_cbcr_array[:,:,1])**2+(cr_key-fg_cbcr_array[:,:,2])**2)
temp2 = np.sqrt((cb_key-fg_cbcr_array[500,500,1])**2+(cr_key-fg_cbcr_array[500,500,2])**2)
print temp[500, 500]
print temp2
Run Code Online (Sandbox Code Playgroud)

上面的输出是

12.039

94.069123521

标量肯定是初始化的,并且数组是使用图像生成的

fg = PIL.Image.open('fg.jpg')
fg_cbcr = fg.convert("YCbCr")
fg_cbcr_array = np.array(fg_cbcr)
Run Code Online (Sandbox Code Playgroud)

EDIT2:

好的,我已经跟踪了我的阵列问题.不知道为什么然而它在使用np.random.random生成数组时有效,但在使用PIL从文件加载时却没有,如上所述.

Sau*_*tro 1

您的矢量化解决方案是正确的。

  • for 循环中temp是一个标量值,仅采用最后一个值
  • 使用np.sqrti 而math.sqrt不是矢量化输入
  • 您不应该将其用作array变量,因为它会影响该np.array方法

我使用以下代码进行了检查,这可能会给您一些有关错误可能出在哪里的提示:

import numpy as np

width = 512
height = 512
scalar1 = 1
scalar2 = 2

a = np.random.random((height, width, 3))
tmp = np.zeros((height, width))
for i in xrange(width):
    for j in xrange(height):
        tmp[j,i] = np.sqrt((scalar1-a[j,i,1])**2+(scalar2-a[j,i,2])**2)

tmp2 = np.sqrt((scalar1-a[:,:,1])**2+(scalar2-a[:,:,2])**2)

np.allclose(tmp, tmp2)
Run Code Online (Sandbox Code Playgroud)

  • 稍后我将循环中的温度分配给二维数组。更改为 np.sqrt 会产生相同的结果:循环符合预期,而我的矢量化版本则不然。它们实际上不是我的变量名称,我将编辑原始问题以显示特定的测试用例。 (2认同)