创建数组时出现奇怪的NumPy错误

时间:2016-03-31 15:01:18

标签: python arrays numpy

使用

foo_ok = [(30, 784), (10, 30)]
foo_bad = [(10, 784), (10, 10)]

为什么

np.array([np.zeros(foo_ok[0]),np.zeros(foo_ok[1])])

工作时

np.array([np.zeros(foo_bad[0]),np.zeros(foo_bad[1])])

结果

  

ValueError:无法将输入数组从形状(10,784)广播到形状(10)

基本上我需要使用foo = [(X, Z), (Y, X)]形式的内容,Y==X可能就是这种情况。但Y==X导致事情失败。

1 个答案:

答案 0 :(得分:3)

根据编辑过的问题编辑答案。

基本上,当第一个轴与2个阵列匹配时,问题依赖于此。下面是一个可复制的例子:

foo_ok = [(30, 784), (10, 30)]
foo_ok2 = [(30, 784), (30, 784)]
foo_bad = [(10, 784), (10, 10)]

如果我们构造前两个数组:

a = np.array([np.zeros(foo_ok[0]),np.zeros(foo_ok[1])])
b = np.array([np.zeros(foo_ok2[0]),np.zeros(foo_ok2[1])])

c = np.array([np.zeros(foo_bad[0]),np.zeros(foo_bad[1])]) # ERROR

我们可以看到生成的数组不一样:

>>> print a.shape, a.dtype, a[0].shape, a[1].shape
(2,), dtype('O'), (30, 784), (10, 30)

>>> print b.shape, b.dtype, b[0].shape, b[1].shape
(2, 30, 784), dtype('float64'), (30, 784), (30, 784)

此处foo_ok2[0]foo_ok2[1]具有相同的值,因此,它将创建2个相同形状的数组。当2个具有相同维度的数组到来时,Numpy smart 足以处理数组连接,并且生成的b数组是形状(2, 30, 784)的串联。但是,生成的数组a只是一个包含2个元素的object类型的数组。列表中的每个元素都是一个不同的数组(如果它是一个原始的python列表)。

Numpy未针对object数组进行优化,因此,只要有可能,它会尝试将数组转换为数值数据类型。

这就是发生的情况,然后2个数组的第一个维度在c中匹配。 Numpy希望所有维度都匹配,从而引发I cannot concatenate this异常。

虽然我仍然鼓励不使用带有对象类型的numpy数组,但是即使第一个轴匹配而数组具有不同的形状,也可以使用 dirty 方式创建一个:

>>> c = np.array([np.zeros(foo_bad[0]), None])
>>> c[1] = np.zeros(foo_bad[1])

>>> print c.shape, c.dtype, c[0].shape, c[1].shape
(2,), dtype('O'), (10, 784), (10, 10)

它的另一个版本(与你的语法密切相关):

>>> c = np.empty((2,), dtype=np.object)
>>> c[:] = [np.zeros(foo_bad[0]), np.zeros(foo_bad[1])]

>>> print c.shape, c.dtype, c[0].shape, c[1].shape
(2,), dtype('O'), (10, 784), (10, 10)