我正在尝试使用 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)
现在您可以使用此数组向其追加形状相似的行。请记住,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.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更像是连接,它创建一个新数组并用旧数组中的值和要附加的新值填充它。例如:
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,)。这些形状不匹配,因此您会收到错误消息。
这是在 Ipython 中运行代码的结果。请注意,这result是一个(2,0)数组,2 行,0 列,0 个元素。append产生一个(2,)数组 。result[0]是(0,)数组。您的错误消息与尝试将该 2 项数组分配到大小为 0 的插槽有关。由于resultis 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?
此错误源于您试图将形状 (0,) 的对象定义为形状 (2,) 的对象。如果您附加您想要的内容而不强制它等于 result[0] 则没有任何问题:
b = np.append([result[0]], [1,2])
但是,当您定义 result[0] = b 时,您将等同于不同形状的对象,您不能这样做。你想做什么?
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])
SO线程'将两个数组元素相乘,其中一个数组将数组作为元素'有一个从数组构造数组的示例。如果子数组的大小相同,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())来生成一个二维数组。