不成功附加到空的NumPy数组

时间:2013-10-28 23:08:16

标签: python arrays numpy append

我试图使用append填充一个空的(不是np.empty!)数组,但是我得到了错误:

我的代码如下:

import numpy as np
result=np.asarray([np.asarray([]),np.asarray([])])
result[0]=np.append([result[0]],[1,2])

我得到了:

ValueError: could not broadcast input array from shape (2) into shape (0)

6 个答案:

答案 0 :(得分:60)

我可能会错误地理解这个问题,但如果您想声明某个形状的数组但内部没有任何内容,则以下内容可能会有所帮助:

初始化空数组:

>>> a = np.array([]).reshape(0,3)
>>> a
array([], shape=(0, 3), dtype=float64)

现在您可以使用此数组向其追加相似形状的行。请记住,numpy数组是不可变的,因此为每次迭代创建一个新数组:

>>> for i in range(3):
...     a = np.vstack([a, [i,i,i]])
...
>>> a
array([[ 0.,  0.,  0.],
       [ 1.,  1.,  1.],
       [ 2.,  2.,  2.]])

np.vstack和np.hstack是组合numpy数组的最常用方法,但来自Matlab我更喜欢np.r_和np.c _:

连接1d:

>>> a = np.array([])
>>> for i in range(3):
...     a = np.r_[a, [i, i, i]]
...
>>> a
array([ 0.,  0.,  0.,  1.,  1.,  1.,  2.,  2.,  2.])

连接行

>>> a = np.array([]).reshape(0,3)
>>> for i in range(3):
...     a = np.r_[a, [[i,i,i]]]
...
>>> a
array([[ 0.,  0.,  0.],
       [ 1.,  1.,  1.],
       [ 2.,  2.,  2.]])

连接列:

>>> a = np.array([]).reshape(3,0)
>>> for i in range(3):
...     a = np.c_[a, [[i],[i],[i]]]
...
>>> a
array([[ 0.,  1.,  2.],
       [ 0.,  1.,  2.],
       [ 0.,  1.,  2.]])

答案 1 :(得分:34)

numpy.append与python中的list.append非常不同。我知道那些新的numpy程序员已经抛弃了。 numpy.append更像是连接,它创建一个新数组并使用旧数组中的值和要追加的新值填充它。例如:

import numpy

old = numpy.array([1, 2, 3, 4])
new = numpy.append(old, 5)
print old
# [1, 2, 3, 4]
print new
# [1, 2, 3, 4, 5]
new = numpy.append(new, [6, 7])
print new
# [1, 2, 3, 4, 5, 6, 7]

我认为您可以通过以下方式实现目标:

result = numpy.zeros((10,))
result[0:2] = [1, 2]

# Or
result = numpy.zeros((10, 2))
result[0, :] = [1, 2]

更新

如果你需要使用循环创建一个numpy数组,并且你不知道数组的最终大小是什么,你可以做类似的事情:

import numpy as np

a = np.array([0., 1.])
b = np.array([2., 3.])

temp = []
while True:
    rnd = random.randint(0, 100)
    if rnd > 50:
        temp.append(a)
    else:
        temp.append(b)
    if rnd == 0:
         break

 result = np.array(temp)

在我的示例中,结果将是一个(N,2)数组,其中N是循环运行的次数,但显然您可以根据需要进行调整。

新更新

您看到的错误与类型无关,它与您尝试连接的numpy数组的形状有关。如果您执行np.append(a, b) ab的形状需要匹配。如果你附加一个(2,n)和(n,)你会得到一个(3,n)数组。您的代码正在尝试将(1,0)附加到(2,)。这些形状不匹配,因此您会收到错误。

答案 2 :(得分:3)

此错误源于您尝试将形状对象(0,)定义为形状对象(2,)的事实。如果你追加你想要的东西而不强迫它等于result [0],那就没有任何问题:

b = np.append([result[0]], [1,2])

但是当你定义result [0] = b时,你将等同于不同形状的对象,而你却无法做到这一点。你想做什么?

答案 3 :(得分:3)

这是在Ipython中运行代码的结果。请注意,result(2,0)数组,2行,0列,0个元素。 append生成(2,)数组。 result[0](0,)数组。您的错误消息与尝试将该2项数组分配到0大小的插槽有关。由于resultdtype=float64,因此只能为其元素分配标量。

In [65]: result=np.asarray([np.asarray([]),np.asarray([])])

In [66]: result
Out[66]: array([], shape=(2, 0), dtype=float64)

In [67]: result[0]
Out[67]: array([], dtype=float64)

In [68]: np.append(result[0],[1,2])
Out[68]: array([ 1.,  2.])

np.array不是Python列表。数组的所有元素都是相同的类型(由dtype指定)。另请注意,result不是数组数组。

结果也可以构建为

ll = [[],[]]
result = np.array(ll)

,而

ll[0] = [1,2]
# ll = [[1,2],[]]

结果不一样。

np.zeros((2,0))也会产生result

实际上result还有另一个怪癖。

result[0] = 1

不会更改result的值。它接受赋值,但由于它有0列,因此无法放置1。此分配在结果中有效,创建为np.zeros((2,1))。但是仍然无法接受清单。

但是如果result有2列,那么你可以为其中一行分配一个2元素列表。

result = np.zeros((2,2))
result[0] # == [0,0]
result[0] = [1,2]

result操作后,您希望append到底是什么样子?

答案 4 :(得分:2)

numpy.append总是在附加新值之前复制数组。您的代码等同于以下内容:

import numpy as np
result = np.zeros((2,0))
new_result = np.append([result[0]],[1,2])
result[0] = new_result # ERROR: has shape (2,0), new_result has shape (2,)

也许你的意思是这样做?

import numpy as np
result = np.zeros((2,0))
result = np.append([result[0]],[1,2])

答案 5 :(得分:1)

SO线程'Multiply two arrays element wise, where one of the arrays has arrays as elements'有一个从数组构造数组的例子。如果子数组的大小相同,则numpy会生成一个二维数组。但如果它们的长度不同,则会生成一个带有dtype=object的数组,并且子数组保留其身份。

之后,您可以这样做:

In [5]: result=np.array([np.zeros((1)),np.zeros((2))])

In [6]: result
Out[6]: array([array([ 0.]), array([ 0.,  0.])], dtype=object)

In [7]: np.append([result[0]],[1,2])
Out[7]: array([ 0.,  1.,  2.])

In [8]: result[0]
Out[8]: array([ 0.])

In [9]: result[0]=np.append([result[0]],[1,2])

In [10]: result
Out[10]: array([array([ 0.,  1.,  2.]), array([ 0.,  0.])], dtype=object)

但是,我并没有随意看到它对纯Python列表或列表有什么好处。它不像二维数组那样工作。例如,我必须使用result[0][1],而不是result[0,1]。如果子数组的长度都相同,我必须使用np.array(result.tolist())来生成一个二维数组。