我弄明白我不理解的np.array
函数的某些行为。这段代码按我期望的方式工作:
arr1 = np.zeros((3,2))
arr2 = np.zeros((2,2))
np.array([arr1,arr2])
array([ array([[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]]),
array([[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]])], dtype=object)
但是这段代码给了我一个错误:
arr1 = np.zeros((2,3))
arr2 = np.zeros((2,2))
np.array([arr1,arr2])
ValueError:无法将形状(2,3)的输入数组广播为形状(2)
为什么它会有所不同,第一个维度的大小是否匹配?我如何强制该函数的行为与第一个示例中的一样?
答案 0 :(得分:2)
对象数组的创建方式发生了变化。尽可能np.array
尝试创建多维数组。创建对象数组一直是后备选择,在输入不匹配时使用。即使这样,也可能无法预测。
最可靠的方法是制作一个大小合适的空对象数组并插入对象
In [242]: a=np.zeros((2,3));b=np.ones((2,2))
In [243]: arr=np.zeros((2,), object)
In [244]: arr[0]=a; arr[1]=b
In [245]: arr
Out[245]:
array([array([[ 0., 0., 0.],
[ 0., 0., 0.]]),
array([[ 1., 1.],
[ 1., 1.]])], dtype=object)
In [246]: arr[:]=[a,b] # also works
您已经看到np.array([a.T, b])
有效。如果我将数组转换为嵌套列表,我会得到一个二维数组的平面列表; 2和3元素列表是不兼容对象的最低级别。
In [250]: np.array([a.tolist(),b.tolist()])
Out[250]:
array([[[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]],
[[1.0, 1.0], [1.0, 1.0]]], dtype=object)
In [251]: _.shape
Out[251]: (2, 2)
np.array
已编译,因此需要进行一些挖掘来解码其逻辑。我之前的挖掘表明,进行了一些更改以加速从数组创建数组(更像是连接)。这个问题可能是这种变化的副作用。
带回家的消息是:如果你想创建一个数组的对象数组,不要依靠np.array
来完成工作。它的设计主要是为了制作多维的标量数组。
例如,如果数组大小匹配:
In [252]: np.array([a,a]).shape
Out[252]: (2, 2, 3)
如果我想要一个2元素的对象数组,我必须使用arr[...]=[a,a]
。