如果numpy.add有2个参数,则将它们作为添加的两个操作数.如果给出3个参数,前两个是添加的,第三个是结果.实际上不是结果,而是应该保存结果的数组.
所以你用b添加了b并希望将它存储在[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)
# returns array([ 2., 2., 2., 2., 2., 2.])
所以现在我尝试了[1:3,0:3] .flat,它返回< numpy.flatiter,位于0x22204e80c10>.这意味着它返回一个迭代器,因此它不是数组.但是我们不需要一个我们想要一个数组的迭代器.有一种叫做ravel()的方法.所以尝试[1:3,0:3] .ravel()会返回:
array([ 0., 0., 0., 0., 0., 0.])
所以我们有一个数组.特别是阵列也可用于存储结果(相同的形状!).所以我尝试过:
np.add(b, b, a[1:3, 0:3].ravel())
# array([ 2., 2., 2., 2., 2., 2.])
但是让我们看看是否有变化:
a
#array([[ 0., 0., 0., 0., 0.],
# [ 0., 0., 0., 0., 0.],
# [ 0., 0., 0., 0., 0.],
# [ 0., 0., 0., 0., 0.]])
所以一个没有改变.这是因为ravel()只返回一个视图(赋值将传播到unraveled数组),否则它会返回一个副本.将结果保存在副本中是没有意义的,因为out参数的重点是操作是就地完成的.我只是猜测为什么要制作副本,但我认为这是因为我们从一个较大的数组中取出一部分,其中该部分在内存中不连续.
所以我建议你不要在这种情况下使用out参数,而是使用np.add的返回并将其存储在指定区域中:
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.]])
此外,[1:3,0:3] .flat = np.add(b,b)也有效.
我认为这本书要么已经过时了,而且它与较旧的numpy版本一起工作,或者它根本就没用过,这本书就是一个错误.