我试图使用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)
答案 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)
a
和b
的形状需要匹配。如果你附加一个(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大小的插槽有关。由于result
为dtype=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())
来生成一个二维数组。