如果您给
numpy.add
提供了两个参数,它们将被视为要进行
加法
的两个操作数。如果您提供了三个参数,则前两个参数将被添加在一起,并且第三个参数是
结果
所在的数组。实际上不是结果,而是应该保存结果的数组。
所以您想把
b
和
b
相加,并将其存储在
a[1:3, 0:3].flat
中。
让我们尝试一下
np.add(b, b)
,得到以下结果:
import numpy as np
a = np.zeros((4, 5))
b = np.ones(6)
np.add(b, b)
所以现在我尝试使用 a[1:3, 0:3].flat
,它返回了 <numpy.flatiter at 0x22204e80c10>
。这意味着它返回了一个 iterator
,而不是一个数组。但我们不需要一个迭代器,我们需要一个数组。有一个叫做 ravel()
的方法。因此,尝试使用 a[1:3, 0:3].ravel()
返回:
array([ 0., 0., 0., 0., 0., 0.])
我们有一个数组。特别地,这个数组也可以用来存储结果(形状相同!)。所以我尝试了:
np.add(b, b, a[1:3, 0:3].ravel())
但是让我们看看a
是否已经改变:
a
#array([[ 0., 0., 0., 0., 0.],
# [ 0., 0., 0., 0., 0.],
# [ 0., 0., 0., 0., 0.],
# [ 0., 0., 0., 0., 0.]])
所以
a
没有改变。这是因为如果可能的话,
ravel()
仅返回视图(赋值将传播到展开的数组),否则它将返回副本。在副本中保存结果相当无意义,因为
out
参数的整个目的是在原地完成操作。我只是猜测为什么会制作副本,但我认为这是因为我们从更大的数组中取出一部分,其中该部分在内存中不连续。
因此,在这种情况下,我建议您不使用out
参数,而是使用np.add
的返回值,并将其存储在a
中指定的区域内:
a[1:3, 0:3] = np.add(b, b).reshape(2,3) # You need to reshape here!
a
#array([[ 0., 0., 0., 0., 0.],
# [ 2., 2., 2., 0., 0.],
# [ 2., 2., 2., 0., 0.],
# [ 0., 0., 0., 0., 0.]])
同时,a[1:3, 0:3].flat = np.add(b, b)
也是可行的。
我认为这本书可能过时了,并且它适用于旧版本的numpy
,或者它从来没有起作用,只是书中的错误。
a[1:3, 0:3].flat = np.add(b, b)
也可以工作。而且这应该等同于您的np.add(b, b, a[1:3, 0:3].flat)
。 - MSeiferta[...].flat=np.add(b,b)
是可行的。flat
文档显示了这种赋值的用法。显然,某些更改已禁用其作为ufunc
out
参数的使用。 - hpaulj