为什么我在尝试强制转换np.array时遇到错误(some_list)ValueError:无法广播输入数组

时间:2014-11-12 11:09:43

标签: python arrays python-3.x numpy multidimensional-array

我试图创建不同形状的np.array的np.array。我需要它,因为在下一部分中,我将总结这个大型np.array与一些具有相同形状的delta_array。 像矩阵一样      self.weights += delta_weights 我将分别处理其中的每个阵列。或者例如,我需要将所有数组的元素乘以某个数字。

无法弄清楚错误:(请帮助我。 代码创建不同形状的随机np.arrays列表。 所以这是我的代码:

weights = []
for i in range(1, len(self.layers)):
    weights.append(np.random.rand(self.layers[i-1] + 1, self.layers[i]))
print(type(weights))
print([(type(w), w.shape) for w in weights])
#error here with layers = [2,2,1] or [3,3,1] etc
self.weights = np.array(weights)

输出: 对于self.layers = [2,2,1]

<class 'list'>
[(<class 'numpy.ndarray'>, (3, 2)), (<class 'numpy.ndarray'>, (3, 1))]
Traceback (most recent call last):
line 20, in <module>
 run()
line 8, in run
 net.init_weights()
line 71, in init_weights
 self.weights = np.array(weights)
ValueError: could not broadcast input array from shape (3,2) into shape (3)

对于[2,3,1],一切都还可以:

<class 'list'>
[(<class 'numpy.ndarray'>, (3, 3)), (<class 'numpy.ndarray'>, (4, 1))]

对于[3,3,1]同样的故事[2,2,1] - 错误

对于[3,7,1]或[3,2,1],一切都还可以。

//用于机器学习的梯度下降的权重矩阵。

2 个答案:

答案 0 :(得分:3)

好的,您正在尝试创建一个矩阵数组,以便稍后可以使用数组操作(如+=)。

你可以声明一个ndarray来容纳另一个ndarray,然后用矩阵填充它(它们只是二维的ndarrays):

weights = np.empty(len(self.layers), dtype=np.ndarray)
for i in range(1, len(self.layers)):
    weights[i] = np.random.rand(self.layers[i-1] + 1, self.layers[i])

请记住,这绝对不是一个三维数组:它纯粹是一个二维数组的数组。

您的代码适用于[2, 3, 1]的原因是广播的是一维1的数组;根据我的理解,这纯粹是偶然的,而不是你想要的。

答案 1 :(得分:2)

当您给np.array一个数组列表时,它会尝试将它们组合成一个数组(具有更高的ndim)。只有它不能合并它们才会创建一个dtype object数组,每个插槽中都有一个数组。

[2,3,1]案例中,2个数组是(3,3)(4,1)。由于没有办法'堆叠'这些,它会创建一个包含这2个的2元素数组。

[3,3,1]案例中,2个数组是(4,3)(4,1)。由于尺寸重叠(4行),它似乎试图将它们连接成一个数组,可能是(2,4,?),但不是很成功。在您的版本中它会引发错误,在我的版本中它会创建一个(2,4) Nones数组。

Evert的解决方案是一个正确处理这些令人困惑的案例的解决方案。即使weights中的2个数组大小相同,它仍然有效。

比如说,如果您的weights包含2个(4,3)数组。 np.arrays(weights)将生成(2,4,3)数组。 Evert的解决方案仍然会生成一个包含2个(2,)数组的(4,3)数组。

在不同的numpy版本中看起来有一个错误(或两个)。带有1.8.0 numpy的Python3处理[2,2,1]的情况就好了。

更简单的测试用例是:

np.array([np.ones((2,2)), np.zeros((2,1))])

围绕2个阵列的尺寸进行游戏。它应该在大多数情况下产生2个元素数组,如果2个尺寸相同则产生(2,n,m)数组。