【问题标题】:python numpy ValueError: operands could not be broadcast together with shapespython numpy ValueError:操作数无法与形状一起广播
【发布时间】:2014-08-24 23:12:08
【问题描述】:

在 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) 更正此问题,但原始问题仍然存在。

【问题讨论】:

  • 什么是“原始问题”? X*y 不应该工作(而且它不工作),但 np.dot(X,y) 和 X.dot(y)) 应该工作(对我来说他们可以)。
  • * 不是 ndarray 对象的矩阵乘法。
  • 我在解决 w.T * X 时遇到了同样的问题,而这应该是 np.dot(w.T,X)
  • X*y 进行元素乘法

标签: python numpy


【解决方案1】:

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

(请注意,如果X和y的类型是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)

【讨论】:

    【解决方案2】:

    每numpy docs:

    当对两个数组进行操作时,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]])
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

        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 显然是错误的(12x1 X 1x5 = 12x5 不能按元素相乘 5x12)但是 numpy 会给你

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

        该错误具有误导性;但是那条线上有一个问题。

        【讨论】:

        • 该错误消息确实具有误导性,因为当您的矩阵维度对于元素乘法错误时,这似乎会出现。
        【解决方案5】:

        使用np.mat(x) * np.mat(y),就可以了。

        【讨论】:

          【解决方案6】:

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

          但其实是广播。

          点积: a.dot(b)

          广播:

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

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

          【讨论】:

            【解决方案7】:

            将数组转换为矩阵,然后进行乘法运算。

            X = np.matrix(X)
            
            y = np.matrix(y)
            
            X*y
            

            【讨论】:

              【解决方案8】:
              ValueError: operands could not be broadcast together with shapes (x ,y) (a ,b)
              where  x ,y are variables
              
              Basically this error occurred when value of y (no. of columns) doesn't equal to the number of elements in another multidimensional array.
              
              Now let's go through by ex=>
              coding  apart
              
                  {
                      import numpy as np 
                      arr1= np.arange(12).reshape(3,4)
                  }
              
              output of arr1
              
              array([[ 0,  1,  2,  3],
                     [ 4,  5,  6,  7],
                     [ 8,  9, 10, 11]])
              
               
              
                  {   arr2= np.arange(4).reshape(1,4)
                        or                   { both are same 1 rows and 4 columns
                      arr2= np.arange(4)
                  }
              
              ouput of arr2=>
              
              array([0, 1, 2, 3])
               
              no of elements in arr2 is equal no of no. of the columns in arr1 it will be excute.
              
                  {
                  for x,y in np.nditer([a,b]):
                      print(x,y)
                  }
              
              output => 0 0
              1 1
              2 2
              3 3
              4 0
              5 1
              6 2
              7 3
              8 0
              9 1
              10 2
              11 3
              

              【讨论】:

              • 请不要只贴代码,多解释帮助别人
              • 对不起先生,我是这个平台的新手。你会帮我吗?我能做的更好吗?
              【解决方案9】:

              关于广播,我们应该考虑两点。 第一:什么是可能的。 第二:有多少可能的事情是由numpy完成的。

              我知道这可能看起来有点混乱,但我会通过一些例子说明清楚。

              让我们从零开始。

              假设我们有两个矩阵。第一个矩阵有三个维度(命名为 A),第二个有五个维度(命名为 B)。 numpy 尝试匹配最后/尾随维度。所以numpy不关心B的前两个维度。 然后 numpy 将这些尾随维度相互比较。并且当且仅当它们相等或其中一个为 1 时,numpy 会说“好的,你们两个匹配”。如果这些条件不满足,numpy 会“抱歉……这不是我的工作!”。

              但我知道您可能会说比较最好以可设计时可以处理的方式进行(4 和 2 / 9 和 3)。您可能会说它可以通过整数复制/广播(示例中为 2/3)。我同意你的看法。这就是我开始讨论的原因是区分什么是可能的和什么是 numpy 的能力。

              【讨论】:

                【解决方案10】:

                这是因为 X 和 y 不是同一类型。例如 X 是一个 numpy 矩阵,y 是一个 numpy 数组!

                【讨论】:

                • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。
                猜你喜欢
                • 2012-08-05
                • 2020-06-20
                • 2012-10-31
                • 2013-04-07
                • 2018-02-01
                • 1970-01-01
                • 1970-01-01
                • 2017-09-09
                • 2018-08-18
                相关资源
                最近更新 更多