Numpy - 用切片进行加等操作时出现奇怪的行为

6

当涉及到切片操作时,使用加等于符号得到的答案与显式求和所得的答案不同(前者的答案并非预期结果)。这是由于何种原因导致的呢?是否应该避免使用加等于符号呢?

a = np.arange(10)
b = np.arange(10)
a[3:] += a[:-3]
b[3:] = b[3:] + b[:-3]
print a
#[ 0  1  2  3  5  7  9 12 15 18] 
print b
#[ 0  1  2  3  5  7  9 11 13 15]

4
因为你在第一个情况下是就地修改... - JBernardo
啊,我现在完全明白了——边进行修改边添加。所以我猜答案就是当你有自引用行为(意味着是静态的)时要避免使用加等号。谢谢! - brasqueychutter
1个回答

3

正如JBernardo所说,+= 会就地修改数组。

a[3:] += [a:-3] 类似于以下代码:

>>> import numpy as np
>>> a = np.arange(10)
>>> 
>>> for i in range(3, 10):
...     print('a[{}] ({}) += a[{}] ({})'.format(i, a[i], i-3, a[i-3]))
...     a[i] += a[i-3]
...     print('  a[{}] -> {}'.format(i, a[i]))
... 
a[3] (3) += a[0] (0)
  a[3] -> 3
a[4] (4) += a[1] (1)
  a[4] -> 5
a[5] (5) += a[2] (2)
  a[5] -> 7
a[6] (6) += a[3] (3)
  a[6] -> 9
a[7] (7) += a[4] (5)  # NOTE: not (4)
  a[7] -> 12
a[8] (8) += a[5] (7)
  a[8] -> 15
a[9] (9) += a[6] (9)
  a[9] -> 18

为了避免这种情况,请使用数组的副本:
>>> a = np.arange(10)
>>> a[3:] += np.copy(a[:-3]) # OR np.array(a[:-3])
>>> a
array([ 0,  1,  2,  3,  5,  7,  9, 11, 13, 15])

1
在这里需要注意的另一个关于 += 的问题是,由于它是原地操作,所以它不会像普通赋值一样提升 dtype。因此,类似 a=np.arange(10); a *= np.pi 这样的操作可能不会得到您想要的结果。 - Evan

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