python numpy ValueError:操作数不能与形状一起广播

问题:python numpy ValueError:操作数不能与形状一起广播

在numpy中,我有两个“数组”,X(m,n)y是一个向量(n,1)

使用

X*y

我收到错误

ValueError: operands could not be broadcast together with shapes (97,2) (2,1) 

何时 (97,2)x(2,1)显然是合法的矩阵运算,应该给我一个(97,1)向量

编辑:

我已使用纠正了此X.dot(y)问题,但原始问题仍然存在。

In numpy, I have two “arrays”, X is (m,n) and y is a vector (n,1)

using

X*y

I am getting the error

ValueError: operands could not be broadcast together with shapes (97,2) (2,1) 

When (97,2)x(2,1) is clearly a legal matrix operation and should give me a (97,1) vector

EDIT:

I have corrected this using X.dot(y) but the original question still remains.


回答 0

dot是矩阵乘法,但*还有其他功能。

我们有两个数组:

  • X,形状(97,2)
  • y,形状(2,1)

使用Numpy数组时,该操作

X * y

可以逐个元素地完成,但是可以在一个或多个维度上扩展其中一个或两个值以使其兼容。此操作称为广播。尺寸为1或缺少尺寸的尺寸可用于广播。

在上面的示例中,尺寸不兼容,因为:

97   2
 2   1

此处在第一维中有冲突的数字(97和2)。这就是上面的ValueError所抱怨的。第二个维度可以,因为数字1不会与任何东西冲突。

有关广播规则的更多信息,请访问:http : //docs.scipy.org/doc/numpy/user/basics.broadcasting.html

(请注意,如果Xy的类型为numpy.matrix,则星号可以用作矩阵乘法。我的建议是远离numpy.matrix,它会使事情变得复杂,而不是简化事情。)

您的数组应该可以使用numpy.dot; 如果您在遇到错误numpy.dot,则必须有其他错误。如果形状不适用于numpy.dot,则会得到另一个异常:

ValueError: matrices are not aligned

如果仍然出现此错误,请发布问题的最小示例。与形状像您的数组的乘法示例成功:

In [1]: import numpy

In [2]: numpy.dot(numpy.ones([97, 2]), numpy.ones([2, 1])).shape
Out[2]: (97, 1)

dot is matrix multiplication, but * does something else.

We have two arrays:

  • X, shape (97,2)
  • y, shape (2,1)

With Numpy arrays, the operation

X * y

is done element-wise, but one or both of the values can be expanded in one or more dimensions to make them compatible. This operation are called broadcasting. Dimensions where size is 1 or which are missing can be used in broadcasting.

In the example above the dimensions are incompatible, because:

97   2
 2   1

Here there are conflicting numbers in the first dimension (97 and 2). That is what the ValueError above is complaining about. The second dimension would be ok, as number 1 does not conflict with anything.

For more information on broadcasting rules: http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html

(Please note that if X and y are of type numpy.matrix, then asterisk can be used as matrix multiplication. My recommendation is to keep away from numpy.matrix, it tends to complicate more than simplify things.)

Your arrays should be fine with numpy.dot; if you get an error on numpy.dot, you must have some other bug. If the shapes are wrong for numpy.dot, you get a different exception:

ValueError: matrices are not aligned

If you still get this error, please post a minimal example of the problem. An example multiplication with arrays shaped like yours succeeds:

In [1]: import numpy

In [2]: numpy.dot(numpy.ones([97, 2]), numpy.ones([2, 1])).shape
Out[2]: (97, 1)

回答 1

每个numpy文档

在两个数组上运算时,NumPy逐元素比较其形状。它从尾随尺寸开始,一直向前发展。在以下情况下,两个维度兼容:

  • 它们相等,或者
  • 其中之一是1

换句话说,如果您试图将两个矩阵相乘(在线性代数意义上),那么您就想要,X.dot(y)但是如果您尝试将标量从矩阵广播y到,X则需要执行X * y.T

例:

>>> import numpy as np
>>>
>>> X = np.arange(8).reshape(4, 2)
>>> y = np.arange(2).reshape(1, 2)  # create a 1x2 matrix
>>> X * y
array([[0,1],
       [0,3],
       [0,5],
       [0,7]])

Per numpy docs:

When operating on two arrays, NumPy compares their shapes element-wise. It starts with the trailing dimensions, and works its way forward. Two dimensions are compatible when:

  • they are equal, or
  • one of them is 1

In other words, if you are trying to multiply two matrices (in the linear algebra sense) then you want X.dot(y) but if you are trying to broadcast scalars from matrix y onto X then you need to perform X * y.T.

Example:

>>> import numpy as np
>>>
>>> X = np.arange(8).reshape(4, 2)
>>> y = np.arange(2).reshape(1, 2)  # create a 1x2 matrix
>>> X * y
array([[0,1],
       [0,3],
       [0,5],
       [0,7]])

回答 2

该错误可能不是在点积中发生的,而是在此之后发生的。例如试试这个

a = np.random.randn(12,1)
b = np.random.randn(1,5)
c = np.random.randn(5,12)
d = np.dot(a,b) * c

np.dot(a,b)会很好的;但是np.dot(a,b)* c显然是错误的(12×1 X 1×5 = 12×5不能逐个元素乘以5×12),但是numpy会给你

ValueError: operands could not be broadcast together with shapes (12,1) (1,5)

错误是令人误解的。但是那条线上有一个问题。

It’s possible that the error didn’t occur in the dot product, but after. For example try this

a = np.random.randn(12,1)
b = np.random.randn(1,5)
c = np.random.randn(5,12)
d = np.dot(a,b) * c

np.dot(a,b) will be fine; however np.dot(a, b) * c is clearly wrong (12×1 X 1×5 = 12×5 which cannot element-wise multiply 5×12) but numpy will give you

ValueError: operands could not be broadcast together with shapes (12,1) (1,5)

The error is misleading; however there is an issue on that line.


回答 3

使用np.mat(x) * np.mat(y),它将起作用。

Use np.mat(x) * np.mat(y), that’ll work.


回答 4

您正在寻找np.matmul(X, y)。在Python 3.5+中,您可以使用X @ y

You are looking for np.matmul(X, y). In Python 3.5+ you can use X @ y.


回答 5

我们可能会混淆a * b是点积。

但实际上,它是广播。

点积: a.dot(b)

广播:

术语广播是指numpy在算术运算期间如何处理具有不同尺寸的数组,这会导致某些约束,较小的数组将在较大的数组上广播,以使它们具有兼容的形状。

(m,n)+-/ *(1,n)→(m,n):该操作将应用于m行

We might confuse ourselves that a * b is a dot product.

But in fact, it is broadcast.

Dot Product : a.dot(b)

Broadcast:

The term broadcasting refers to how numpy treats arrays with different dimensions during arithmetic operations which lead to certain constraints, the smaller array is broadcast across the larger array so that they have compatible shapes.

(m,n) +-/* (1,n) → (m,n) : the operation will be applied to m rows