【问题标题】:Numpy Matrix Subtraction ConfusionNumpy 矩阵减法混淆
【发布时间】:2013-03-25 15:16:55
【问题描述】:

我对意外使用两个 numpy 矩阵(后来修复)执行的操作的结果有疑问。

假设我有一个列向量 A = [1,2,3] 和一个行向量 B = [1,1,1]。据我所知,没有正确的数学方法可以“减去”这两个向量,即这应该是一个未定义的操作。然而,当我这样做时,我又回来了:

>>> matrix([[0, 1, 2],
            [0, 1, 2],
            [0, 1, 2]])

我以为这可能是某种广播操作,但这仍然让我有些困扰。 numpy.matrix 对象不应该只包含数学上有效的矩阵运算吗?

感谢任何帮助!

谢谢!

【问题讨论】:

  • 知道会很有趣。
  • 谷歌“numpy 广播”
  • @user1149913 我认为问题不在于广播是如何工作的,而在于为什么允许一行与列向量相加/减去?另外,请记住,np.matrix 的广播规则与 np.ndarray 的广播规则大不相同。
  • @askewchan matrix 子类ndarray,它们遵循完全相同的广播规则。主要区别在于__getitem__ 方法,它确保始终保留2D 对象,而__mul__ 调用.dot 而不是np.multiplyThe source is pure Python 易于理解。
  • 不鼓励使用np.matrix,部分原因是这种不一致的行为。如果您一直使用 1D ndarray,则不会意外得到 2D 数组。对于np.ndarray,广播是一个定义明确的操作,同样的规则也适用于它的matrix 子类,即使它不是你对“数学矩阵”的期望。

标签: python matrix numpy


【解决方案1】:

A 和 B 一起广播:

A = np.matrix([[1],[2],[3]])
#a 3x1 vector
#1
#2
#3

B = np.matrix([[1,1,1]])
#a 1x3 vector
#1 1 1

A-B
#a 3x3 vector
#0 0 0
#1 1 1
#2 2 2

A 沿其大小 1 维(列)广播到

#1 1 1
#2 2 2
#3 3 3

B 沿其大小 1 维(行)广播到

#1 1 1
#1 1 1
#1 1 1

然后像往常一样为两个 3x3 矩阵计算 A-B。

如果您想知道它为什么这样做而不是报告错误,那是因为 np.matrix 继承自 np.array。 np.matrix 覆盖乘法,但不覆盖加法和减法,因此它使用基于 np.array 的操作,当维度允许时广播。

【讨论】:

  • 但是你必须小心谁在使用它。数学家和物理学家不一定知道这一点(即使快速谷歌可以告诉你),并且会假设这应该返回一个错误,而它显然不知道。在我看来, np.matrix 也应该覆盖加法和减法。这是我们在这里谈论的一个数学库。
  • 我同意 astromax。在处理矩阵对象时,我认为最好默认抛出错误或异常,而不是执行意外操作。 Matlab 做对了
【解决方案2】:

我无法真正解释原因,因为我经常使用np.matrix 而不是np.array 来防止这种事情发生。感谢@Jaime 在上面 cmets 中的链接,很明显 np.matrix 只是 np.ndarray 的一个子类,具有重新定义的中缀运算,其中有来自线性代数的适当答案。如果没有,则使用 np.ndarrayndim = 2 的规则。

似乎加法遵循矩阵乘法规则A 中的哪些元素与B 中的哪些元素配对:

In [1]: import numpy as np
In [2]: A = np.matrix([1,2,3]).T
In [3]: B = np.matrix([1,1,1])

In [4]: A
Out[4]: 
matrix([[1],
        [2],
        [3]])

In [5]: B
Out[5]: matrix([[1, 1, 1]])

In [6]: A+B
Out[6]: 
matrix([[2, 2, 2],
        [3, 3, 3],
        [4, 4, 4]])

In [7]: A*B
Out[7]: 
matrix([[1, 1, 1],
        [2, 2, 2],
        [3, 3, 3]])

这与np.array 的行为相同:

In [9]: a = np.arange(3)[...,None]

In [10]: b = np.arange(3)

In [11]: a
Out[11]: 
array([[0],
       [1],
       [2]])

In [12]: b
Out[12]: array([0, 1, 2])

In [13]: a+b
Out[13]: 
array([[0, 1, 2],
       [1, 2, 3],
       [2, 3, 4]])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-25
    • 1970-01-01
    • 2015-12-17
    • 2020-10-01
    • 2012-01-20
    • 2019-11-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多