【问题标题】:How does the following code work for Matrix Multiplication in Python以下代码如何用于 Python 中的矩阵乘法
【发布时间】:2019-03-02 12:21:54
【问题描述】:

我正在尝试在 python 中进行矩阵乘法,我发现了以下我想要理解的代码。 (我知道如何手动将矩阵相乘,我想了解以下代码如何执行相同的操作,我的意思是 BA 中的第一个元素(第 1 行第 1 列)是通过执行 (1*1 + 3*3 + 3*3 + 1*1) 等。

from numpy import array
A= array([[ 1, 4, 5 ],[ 3, 2, 9], [ 3,6, 2], [ 1,6, 8]])
B=A.T

BA= array([[ 0, 0, 0 ],[ 0,0, 0], [ 0,0, 0] ])

for i in range(len(B)):
   for j in range(len(A[0])):
       for k in range(len(A)):
           BA[i][j] += B[i][k] * A[k][j]

我知道列表的长度命令会返回该列表中有多少元素。我不确定它在这里是如何工作的,因为 B 是一个矩阵,我假设它返回有多少行。

len(B) 的范围将是 (0,3),对应于第 1,2 和 3 行。 for i in range 将对应于 i=0, i=1, i= 2

下一个令人困惑的事情是 j in range len(A[0]) A 的第一个元素是第一行,因此这里的长度将对应于 A 的第一个元素中有多少个元素。

基本上我对这个例子的范围和 len 等有一个基本的了解,但我想更好地理解 i、j、k 的每个值,因为这些值以及最后一行我真的不明白。

BA[i][j] += B[i][k] * A[k][j]

请尽可能基本地解释,因为我是编程新手,所以在这一点上对我来说没有什么是微不足道的。感谢您抽出时间帮助他人:)

【问题讨论】:

  • 是否使用numpy.array
  • 我导入了 scipy、pylab 和 sys。不确定 numpy.array 是什么,如果您想知道返回什么,我可以尝试一下并向您展示输出。
  • 您应该避免使用from module import * 语法。您不仅可能会忘记哪个函数或类来自哪个模块,而且还会在您的程序中造成命名混乱和重大问题。
  • array 不能是标准库中的array.array(它有另一个构造签名)。有可能是numpy.array,但这只是假设。查看您的代码:您在某处有from numpy import ... 吗?如果是这样:编辑您的问题并相应地标记。请花点时间阅读:How to create a Minimal, Complete, and Verifiable example 以获得灵感
  • B=A.T 表示矩阵 B 是矩阵 A 的转置。我很欣赏有关避免导入的建议。但由于我处于如此基本的水平,我认为它会很好,如果它有效,我会很高兴。 numpy 包含在 scipy 中吗?那是对的吗。我听说你也可以使用 numpy 的内置“函数”来执行矩阵乘法,我也对如何做到这一点感兴趣。

标签: python numpy


【解决方案1】:

这是您的代码的实际结果:

   B    *   A   =      AB
1 3 3 1   1 4 5     20 34 46
4 2 6 6   3 2 9     34 92 98
5 9 2 8   3 6 2     46 98 174
          1 6 8

假设i = 0j = 0 让我们计算BA[0][0],它是矩阵BA 的第一个元素。

BA[0][0] = B[0][k] * A[k][0]

B[0][k] 表示矩阵 B 的第 0 行。因为k 正在遍历 A 的所有行,其大小与 B 中的列数相同。
A[k][0] 表示第 0 列来自矩阵A。

循环for k in range(len(A)): 将重现:

B[0][0]*A[0][0] + B[0][1]*A[1][0] + B[0][2]*A[2][0] + B[0][3]*A[3][0]

导致:

1×1 + 3×3 + 3×3 + 1×1 = 20

BA[0][0] 的值是由您的代码产生的。

以下嵌套循环将遍历 A 的所有列作为 j 为 B 的每一行作为 i 以执行所有(行)x(列)对的乘法:

for i in range(len(B)):
   for j in range(len(A[0])):

【讨论】:

    【解决方案2】:

    在此处将数组视为您提供给函数的列表的更方便的表示形式。

    A建立在列表[[ 1, 4, 5 ],[ 3, 2, 9], [ 3,6, 2], [ 1,6, 8]]之上,一个长度为4的列表。

    range(start, stop) 是一个函数,它返回一个生成器,它产生一个整数序列,从开始到结束点,停止不包括在内。如果未提供,则 start 默认为 0。

    B 的长度为 4 行,因此 range(len(B)) 将类似于 range(0, 3),当 for 循环“询问”时,它将产生 0,1 和 2 个整数。 i 随后将是 0,1 和 2。

    A[0] 返回 A 的第一行,它的长度为 3,所以同样的方式,j 随后将是 0、1 和 2(在这种情况下);并且 k 随后将是 0、1、2 和 3,因为 A 的长度为 4。

    BA[i] 返回索引i 的行。也可以通过j进行索引 所以 BA[i][j] 是第 i 行第 j 列的元素,我们用第 i 行的元素和矩阵 B 的索引 k 的乘积递增;以及矩阵A的第k行和索引j的元素。

    【讨论】:

      【解决方案3】:

      在您的代码示例中,矩阵表示为一个子列表列表,其中每个子列表是一行。

      所以最外面的循环遍历 B 的行:

      for i in range(len(B)):
      

      A[0]是A的第一行,里面的元素个数就是A的列数。

      所以第二个循环遍历 A 的列:

      for j in range(len(A[0])):
      

      最内层的循环只是简单地将 B 的第 j 行和 A 的第 i 行中的元素的乘积相加。

      BA[i][j] += B[i][k] * A[k][j]
      

      这添加到BA[i][j] 产品。 += 将其右侧参数添加到左侧。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-06-13
        • 2020-12-05
        • 1970-01-01
        • 1970-01-01
        • 2020-07-14
        • 2020-02-17
        • 1970-01-01
        相关资源
        最近更新 更多