numpy 2d和1d加平

时间:2016-02-14 03:57:17

标签: python arrays numpy

在开始使用NumPy时使用NumPy Book中的示例我注意到了一个例子:

a = zeros((4, 5))
b = ones(6)
add(b, b, a[1:3, 0:3].flat)
print(a)

返回

array([[0, 0, 0, 0, 0]
       [2, 2, 2, 0, 0]
       [2, 2, 2, 0, 0]
       [0, 0, 0, 0, 0]])

但是,当我尝试此代码时,会导致以下错误:

  

添加(b,b,a [1:3,0:3] .flat)

     

TypeError:返回数组必须是ArrayType"

有人可以对这个问题有所了解吗?

1 个答案:

答案 0 :(得分:3)

如果numpy.add有2个参数,则将它们视为added的两个操作数。如果给出3个参数,前两个是添加的参数,第三个参数是result。实际上不是结果,而是应保存结果的数组。

因此,您在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)
# returns array([ 2.,  2.,  2.,  2.,  2.,  2.])

所以现在我尝试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())
# array([ 2.,  2.,  2.,  2.,  2.,  2.])

但是,让我们看看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()只返回一个视图(赋值将传播到unraveled数组),否则它会返回一个副本。将结果保存在副本中是没有意义的,因为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版本,或者根本没有用过,这本书就是一个错误。