0

我正在比较同一数组的两个切片。这两个切片是相同的,只是它们在 [1] 轴上偏移。我比较这两个切片并在 while 循环中重复返回它们的最小值。

我的期望:数组的大小相对于彼此保持不变,按“偏移量”的值缩小

相反会发生什么:在第二次迭代中,其中一个数组的大小相对于另一个缩小,缩小幅度超过“offset”的值

由于我使用相同的偏移值来比较它们,并且作为 (xy) - 0 = x - (0 + y),这些值必须相同。对于第一次迭代,它们是相同的,但对于第二次迭代,它们不是,正如您从打印输出中看到的那样。

我认为这个问题可能与按值传递问题有关,所以我尝试使用 copy.deepcopy,但这也不能解决问题。我还认为索引溢出索引可能有一个怪癖,所以我将高度和宽度设置为少一点,以防万一,但这也没有产生任何效果。我想知道我是否可能对切片或高级索引的工作方式有根本的误解。

这是打印输出:

Slice 1: offset value: 1    height, width: 999 1332
Slice 2: offset value: 1    height, width: 999 1332
Slice 1: offset value: 2    height, width: 999 1331
Slice 2: offset value: 2    height, width: 999 1330

这是我得到的错误,它在 while 循环的第二次迭代中触发:

    image = np.minimum(slice1, slice2)

ValueError: operands could not be broadcast together with shapes (999,1331) (999,1330)

这是我的代码:

def horizontal_smear(image, distance):

    height = len(image) - 1
    width  = len(image[0] - 1)
    offset = 1

    while offset < distance /2:

        slice1 = copy.deepcopy(image[0 : height, 0 : (width - offset)])
        print ("Slice 1: offset value:", offset, "   height, width:", len(slice1), len(slice1[0]))        
        slice2 = copy.deepcopy(image[0 : height, offset : width])
        print ("Slice 2: offset value:", offset, "   height, width:", len(slice2), len(slice2[0]))        

        image = np.minimum(slice1, slice2)
        offset *= 2

    return image
4

2 回答 2

0

这解决了阻止功能正常工作的编码错误。它没有解释错误的潜在机制:

在 while 循环中,图像缩小,因此 slice1 和 slice2 的每个后续副本都具有较少的源数据可供绘制,但“高度”和“宽度”保持固定。由于切片 2 比切片 1 更靠右,这会将其推出索引范围之外。(这可能与它的索引缩小的原因有关,但我不知道 numpy 如何处理超出范围的数据。)

将线路更改image = np.minimum(slice1, slice2)

image[0:height, 0:(width - offset)] = np.minimum(slice1, slice2)解决问题。

于 2020-05-05T20:11:30.710 回答
0

您的第二个切片从缩小的image数组的末端运行。问题是您的代码正在重新绑定image到连续更小的数组,但您的width变量保持不变(比原始大小小一个)。您可能需要width在循环内进行更新。

# move the width line from here
offset = 1

while offset < distance /2:
    width = len(image[0] - 1)   # to here

    ...

关于为什么你的代码最终会出现它所做的确切错误的更多细节:当你在 Python 中切掉容器的末尾时(包括 Numpy 数组,它的行为并不总是与其他类型相同),你会得到一个更小的结果超出您的预期,并且没有错误。这是一个带有列表的示例:

a = [1, 2, 3]
b = a[0:2] # len(b) is 2
c = a[2:4] # len(c) is unexpectedly 1!

由于在索引 2 之后没有更多元素,因此要创建的切片会c生成一个元素列表,即使切片表示法可能导致您期望结果具有两个元素(从索引 2-3 开始)。

于 2020-05-05T22:12:46.983 回答