使用numpy数组操作时出现奇怪的行为

5
解释一下这个问题:
>>> a = np.arange(10)
>>> a[2:]
array([2, 3, 4, 5, 6, 7, 8, 9])
>>> a[:-2]
array([0, 1, 2, 3, 4, 5, 6, 7])
>>> a[2:] - a[:-2]
array([2, 2, 2, 2, 2, 2, 2, 2])
>>> a[2:] -= a[:-2]
>>> a
array([0, 1, 2, 2, 2, 3, 4, 4, 4, 5])

预期的结果当然是array([0, 1, 2, 2, 2, 2, 2, 2, 2, 2])
我猜测这与numpy并行处理数据有关,但它没有足够的智能来先制作临时数据副本(或按正确顺序执行操作)。
换句话说,我怀疑它正在做一些像这样的幼稚事情:
for i in range(2, len-2):
    a[i] -= a[i-2]

这段代码用于Matlab和Octave:

a = 0:9
a(3:end) = a(3:end) - a(1:end-2)

a =

  0  1  2  3  4  5  6  7  8  9

a =

  0  1  2  2  2  2  2  2  2  2

如果你执行以下操作,它实际上是有效的:

a[2:] = a[2:] - a[:-2]

所以这意味着对于numpy来说,a -= b 不等同于 a = a - b

事实上,现在我想起来了,我认为Mathworks之所以没有实现+=、-=、/=和*=运算符之一就是出于这个原因!


所以可以推测,对于numpy来说,a -= ba = a - b并不相同!在纯Python中也是如此。https://dev59.com/Q3E95IYBdhLWcg3wWMlQ - Akavall
2个回答

4

1
意外的行为是由于数组别名引起的,因为(正如@JoshAdel在他的回答中所述),切片返回一个视图,而不是数组的副本。你提供的“天真”循环示例已经解释了结果是如何计算的。但我会补充两点来解释:
首先,意外的行为并不是由于numpy并行化操作。如果该操作被并行化,则不应该期望[一致地]看到天真循环的结果(因为该结果取决于循环的有序执行)。即使对于大型数组,如果您重复实验几次,您也应该看到相同的结果。
其次,虽然您的假设通常是正确的,但我会这样陈述:
a b 没有别名时,a -= ba = a - b对于两个numpy数组是相同的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接