【问题标题】:Python 3: Multiply a vector by a matrix without NumPyPython 3:将向量乘以没有 NumPy 的矩阵
【发布时间】:2015-03-30 22:40:28
【问题描述】:

我对 Python 相当陌生,并试图创建一个函数来将向量乘以矩阵(任何列大小)。 例如:

multiply([1,0,0,1,0,0], [[0,1],[1,1],[1,0],[1,0],[1,1],[0,1]])

[1, 1]

这是我的代码:

def multiply(v, G):
    result = []
    total = 0
    for i in range(len(G)):
        r = G[i]
        for j in range(len(v)):
            total += r[j] * v[j]
        result.append(total)
    return result  

问题是,当我尝试选择矩阵 (r[j]) 中每一列的第一行时,会显示错误“列表索引超出范围”。有没有其他不使用 NumPy 完成乘法的方法?

【问题讨论】:

    标签: python python-3.x numpy matrix vector


    【解决方案1】:

    Numpythonic 方法:(使用numpy.dot 以获得两个矩阵的点积)

    In [1]: import numpy as np
    
    In [3]: np.dot([1,0,0,1,0,0], [[0,1],[1,1],[1,0],[1,0],[1,1],[0,1]])
    Out[3]: array([1, 1])
    

    Pythonic 方法:

    您的第二个 for 循环的长度是 len(v) 并且您尝试基于此索引 v 所以您得到索引 Error 。作为一种更 Pythonic 的方式,您可以使用 zip 函数获取列表的列,然后在列表理解中使用 starmapmul

    In [13]: first,second=[1,0,0,1,0,0], [[0,1],[1,1],[1,0],[1,0],[1,1],[0,1]]
    
    In [14]: from itertools import starmap
    
    In [15]: from operator import mul
    
    In [16]: [sum(starmap(mul, zip(first, col))) for col in zip(*second)]
    Out[16]: [1, 1]
    

    【讨论】:

    • 这看起来不适合初学者。
    • @physicalattraction 我将添加更多描述 ;)
    • 谢谢。我没有遇到过 zip 功能 - 让它更容易!最后一件事,当我尝试返回 sum(mul(k,t)) 时收到语法错误。它突出显示了外部方括号,我假设它将总和作为列表返回?
    【解决方案2】:

    我认为您的代码的问题在于您循环遍历矩阵的行而不是列。此外,您不会在每个向量*矩阵列计算后重置您的“总”变量。这就是你想要的:

    def multiply(v, G):
        result = []
        for i in range(len(G[0])): #this loops through columns of the matrix
            total = 0
            for j in range(len(v)): #this loops through vector coordinates & rows of matrix
                total += v[j] * G[j][i]
            result.append(total)
        return result
    

    【讨论】:

      【解决方案3】:

      我附上了矩阵乘法的代码,请遵循一维乘法的示例格式(列表列表)

      def MM(a,b):
      c = []
      for i in range(0,len(a)):
          temp=[]
          for j in range(0,len(b[0])):
              s = 0
              for k in range(0,len(a[0])):
                  s += a[i][k]*b[k][j]
              temp.append(s)
          c.append(temp)
      
      return c
      a=[[1,2]]
      b=[[1],[2]]
      print(MM(a,b))
      

      结果是 [[5]]

      【讨论】:

        【解决方案4】:

        r 是来自G 的一个元素,所以它是一个只有两个元素的行。这意味着您不能使用索引jr 获取值,因为j 从0 到v 的长度,在您的示例中为6。

        【讨论】:

          【解决方案5】:

          我需要第一个矩阵可以是二维的解决方案。从@Kasramvd 扩展解决方案以接受二维first 矩阵。贴在这里供参考:

          >>> first,second=[[1,0,0,1,0,0],[0,1,1,1,0,0]], [[0,1],[1,1],[1,0],[1,0],[1,1],[0,1]]
          >>> from itertools import starmap
          >>> from operator import mul
          >>> [[sum(starmap(mul, zip(row, col))) for col in zip(*second)] for row in first]
          [[1, 1], [3, 1]]
          

          【讨论】:

            【解决方案6】:
            # check matrices
            A = [[1,2],[3,4]]
            B = [[1,4],[5,6],[7,8],[9,6]]
            
            def custom_mm(A,B):    
                if len(A[0]) == len(B): -- condition to check if matrix multiplication is valid or not. Making sure matrix is nXm and mXy
                    result = [] -- final matrix
                    for i in range(0,len(A)): -- loop through each row of first matrix
                        temp = [] -- temporary list to hold output of each row of the output matrix where number of elements will be column of second matrix
                        for j in range(0,len(B[0])): -- loop through each column of second matrix
                            total = 0 
                            l = 0 -- dummy index to switch row of second matrix 
                            for k in range(0,len(A[0])):
                                total += A[i][k]*B[l][j]
                                l = l+1
                            temp.append(total)
                        result.append(temp)                
                    return result
                else:
                    return (print("not possible"))
            
            print(custom_mm(A,B))
            
            
                
            

            【讨论】:

            • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
            【解决方案7】:

            有一个代码可以帮助你将两个矩阵相乘:

            A=[[1,2,3],[4,5,6],[7,8,9]]
            B=[[1,2,3],[4,5,6],[7,8,9]]
            matrix=[]
            
            def multiplicationLineColumn(line,column):
                try:
                    sizeLine=len(line)
                    sizeColumn=len(column)
                    if(sizeLine!=sizeColumn):
                        raise ValueError("Exception")
                    res = sum([line[i] * column[i] for i in range(sizeLine)])
                    return res
                except ValueError:
                    print("sould have the same len line & column")
            
            def  getColumn(matrix,numColumn):
                size=len(matrix)
                column= [matrix[i][numColumn] for i in range(size)]
                return column
            
            def getLine(matrix,numLine):
                line = matrix[numLine]
                return line
            
            for i in range(len(A)):
                matrix.append([])
                for j in range(len(B)):
                    matrix[i].append(multiplicationLineColumn(getLine(A,i),getColumn(B,j)))
            
            print(matrix)
            

            【讨论】:

            • 你能解释一下为什么你的答案比其他人发布的更好吗?
            • @user_3pij 并不比其他人好,但这是一个不使用 numpy 的本机代码我想表明我们可以通过基础 python 完成同样的任务
            猜你喜欢
            • 2020-05-30
            • 2022-11-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-12-12
            • 1970-01-01
            相关资源
            最近更新 更多