【问题标题】:Vectorizing loops in NumPyNumPy 中的向量化循环
【发布时间】:2013-11-19 05:17:29
【问题描述】:

我正在尝试使用 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)

我目前正在做的是:

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

我从中得到的临时数组是所需的维度 (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

上面的输出是

12.039

94.069123521

标量被明确初始化,数组是从图像生成的

fg = PIL.Image.open('fg.jpg')
fg_cbcr = fg.convert("YCbCr")
fg_cbcr_array = np.array(fg_cbcr)

编辑2:

好的,所以我已经找到了我的阵列的问题。不知道为什么,但它在使用 np.random.random 生成数组时有效,但在使用上述 PIL 从文件加载时无效。

【问题讨论】:

  • 这对我来说非常好用,您能否展示一个完整的问题示例。请确保您没有遇到某种机器 epsilon 问题或打印问题。
  • 如果在 for 循环中将 math.sqrt 替换为 np.sqrt,数组是否仍然不同?
  • 是的 np.sqrt 在循环中仍然给我想要的结果
  • 您的测试用例仍然返回与np.random.rand 创建的试验数组完全相同的结果。请举例说明差异。
  • 这些值与我的预期非常不同,所以我不认为这是一个 epsilon 问题。有没有办法比较数组以排除打印问题?当我切换到这个方法时,实现停止工作,我使用打印来追踪它到这条线产生不同的结果。

标签: python arrays numpy vectorization


【解决方案1】:

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

  • 在你的 for 循环中 temp 是一个标量值,它只取最后一个值
  • 使用np.sqrt 而不是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)

【讨论】:

  • 我稍后将循环中的温度分配给二维数组。更改为 np.sqrt 会得到相同的结果:循环符合预期,而我的矢量化版本不是。它们实际上不是我的 var 名称,我将编辑原始问题以显示特定的测试用例。
猜你喜欢
  • 2017-04-29
  • 2013-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多