Python 3:如何在没有NumPy的情况下将向量乘以矩阵?

14

我对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?

7个回答

10

numpy.dot函数是使用NumPy进行矩阵点乘的一种Pythonic方法。

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,所以会导致索引错误。更加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]

5
这似乎不适合初学者。 - physicalattraction
1
@physicalattraction 我会添加更多描述 ;) - Mazdak
谢谢。我之前没有遇到过zip函数 - 这使得它变得更容易了!最后一个问题,当我尝试返回sum(mul(k,t))时,我收到了语法错误。外部方括号被突出显示,我假设它将总和作为列表返回? - JGraham353

4
我认为您的代码存在问题在于您循环遍历了矩阵的行而不是列。另外,在每次向量*矩阵列计算后,您没有重置“total”变量。下面是您需要的代码:
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]]


2

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


2
# 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))


    

1
你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

2

我需要一个解决方案,其中第一个矩阵可以是二维的。扩展@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]]

0

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

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
1
@user_3pij并不比其他人更优秀,但这是一种不使用numpy的本地代码。我想展示我们可以通过基本的Python完成相同的任务。 - Ilyas Maamri

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接