我正在尝试使用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)
我可能误解了问题,但如果您想声明一个特定形状的空数组,以下内容可能会有所帮助:
初始化空数组:
>>> a = np.zeros((0,3)) #or np.empty((0,3)) or np.array([]).reshape(0,3)
>>> a
array([], shape=(0, 3), dtype=float64)
>>> 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.zeros(0)
>>> 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.zeros((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.zeros((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.]])
numpy.append
与Python中的list.append
相比有很大的区别。我知道这点会让一些刚接触numpy的程序员感到困惑。numpy.append
更像是拼接(concatenate),它创建一个新的数组并将旧数组的值和要附加的新值填入其中。例如:
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,)上。这些形状不匹配,因此会出现错误。
b = np.append([result[0]], [1,2])
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
。如果result
创建为np.zeros((2,1))
,那么这个赋值会起作用。但是它仍然无法接受列表。
但是如果result
有2列,那么您可以将一个2元素列表分配给其中一行。
result = np.zeros((2,2))
result[0] # == [0,0]
result[0] = [1,2]
在append
操作之后,您希望result
具体看起来是什么样子?
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])
np.append
就是一个 concatenate
: return concatenate((arr, values), axis=axis)
- hpauljSO线程'逐元素相乘两个数组,其中一个数组的元素是数组'有一个构建由数组组成的数组的示例。如果子数组大小相同,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)
result [0] [1]
而不是result [0,1]
。如果子数组的长度都相同,我必须使用np.array(result.tolist())
来生成一个2D数组。
a = np.zeros((0,3))
。 - Simon Streicher