如果 matrix_a = [[a, b], [c, d]],并且 matrix_b = [[w, x], [y, z]] 计算 matrix_c = [[ a*w + c*y, a*x + c*z], [b*w + d*y, b*x + d*z]] 在 Python 3?

If matrix_a = [[a, b], [c, d]], and matrix_b = [[w, x], [y, z]] compute matrix_c = [[a*w + c*y, a*x + c*z], [b*w + d*y, b*x + d*z]] in Python 3?

如果我有两个矩阵 matrix_a = [[a, b], [c, d]] 和 matrix_b = [[w, x], [y, z]]我希望找到以下矩阵 matrix_c = [[aw + cy, ax + cz], [ bw + dy, bx + dz]] 我怎么能这样做,不仅对于这种情况而且对于任意大小的 matrix_a 和 matrix_b:
a) 最简单地只使用列表综合
b) 最简单地使用一个函数,它将两个矩阵 matrix_a 和 matrix_b 作为输入,并返回 matrix_c
c) and/or 另一种 pythonic 方式?

以下代码是我目前的解决方案。

matrix_a = [[1, 1], [2, 1]]
matrix_b = [[25, 1.5], [30, 2.7]]

# so we should obtain matrix_c = [[85, 6.9], [55, 4.2]]

transposed_matrix_a =[list(i) for i in zip(*matrix_a)]

matrix_c = []
for i in range(len(matrix_a[0])):
    def matrix_element(function, number):
        return [function(number)*matrix_b[number][i] for i in range(len(
            matrix_b[0]))]
        
    def t_matrix_a_element(x):
        return transposed_matrix_a[i][x]

    c_vector = [matrix_element(t_matrix_a_element, i) for i in range(len(
        transposed_matrix_a[0]))]
    matrix_c.append([sum(i) for i in zip(*c_vector)])

print(matrix_c)

编辑: 明确地说,所需的计算是:
matrix_c = [[aw + cy, ax + cz], [bw + dy, bx + dz]]
matrix_c = [[1 x 25 + 2 x 30, 1 x 1.5 + 2 x 2.7], [1 x 25 + 1 x 30, 1 x 1.5 + 1 x 2.7]]
matrix_c = [[85, 6.9], [55, 4.2]]

而不是产品:
[[aw + by, ax + bz], [cw + d y, cx + dz]]

对于 (c) 情况,您可以简单地使用 numpy 模块。

import numpy as np

a = np.array([[1, 1], [2, 1]])
b = np.array([[25, 1.5], [30, 2.7]])

print(a @ b)

[[55. ,  4.2],
 [80. ,  5.7]]

尝试以下操作:

def transpose(matrix):
    # if you just want to iterate over the 
    # transposed matrix, you can just
    # return zip(*matrix)
    return list(map(list, zip(*matrix)))

matrix_c = []

for row_a in matrix_a:
    row_c= []
    for val_a, row_b in zip(row_a, transpose(matrix_b)):
        val_c = sum(val_a * val_b for val_b in row_b)
        row_c.append(val_c)
    matrix_c.append(row_c)

print(result)

# [[55, 4.2], [110, 4.2]]

另一种方式,虽然是手动的,不能自动化,但以防万一:

>>> [[a, b], [c, d]], [[w, x], [y, z]] = matrix_a, matrix_b

>>> matrix_c = [[a*w + a*y, b*x + b*z], [c*w + c*y, d*x + d*z]]

>>> matrix_c
[[55, 4.2], [110, 4.2]]

另一个完全基于列表理解的问题的解决方案:

import numpy as np

#mat_a = [[1, 1], [2, 1]]
#mat_b = [[25, 1.5], [30, 2.7]]
mat_a = np.random.random((3,4))
mat_b = np.random.random((4,5))

def matMul(A, B):
    return [list(map(lambda x:sum([i*j for i,j in x]), [list(zip(row, col)) for row in A for col in [list(i) for i in zip(*B)]]))[s*len(B[0]):s*len(B[0])+len(B[0])] for s in range(len(A)) ]

print(mat_a @ mat_b)
for row in matMul(mat_a, mat_b):
    print(row)

对非 numpy 试试这个: (相信它更像 Pythonic ... ;-) - 比 numpy 版本)

def matrix_mul(A, B):
    zip_b = list(zip(*B))
    return [[sum(a * b for a, b in zip(row_a, col_b))
                 for col_b in zip_b]
            for row_a in A]

# one-liner
""" result = [[ sum(a*b for a,b in zip(X_row,Y_col))
                        for Y_col in zip(*Y)]
              for X_row in X]
                    
"""
matrix_a = [[a, b], [c, d]]
matrix_b = [[w, x], [y, z]]
matrix_c = [[aw + cy, ax + cz], [bw + dy, bx + dz]]

abcdwxyz 不是很有帮助,特别是当有人想泛化任务时,最好用索引重写,比如

A = [a b] = [A11 A12],   B = [w x] = [B11 B12]
    [c d]   [A21 A22]        [y z]   [B21 B22]

C = [a*w+c*y  a*x+c*z] = [A11*B11+A21*B21  A11*B12+A21*B22]
    [b*w+d*y  b*x+d*z]   [A12*B11+A22*B21  A12*B12+A22*B22]

那么就有机会观察

Cij
C11 = A11*B11+A21*B21 = Sum Ak_*Bk_ for k=1,2 and _ could be either i or j
C12 = A11*B12+A21*B22 = Sum Aki*Bkj for k=1,2
C21 = A12*B11+A22*B21 = Sum Aki*Bkj for k=1,2
C22 = A12*B12+A22*B22 = Sum Ak_*Bk_ for k=1,2
Cij = Sum Aki*Bkj

一些你可能知道的事情,尽管继续用那个 abcdwxyz 怪物挖出我们的眼睛。

这是一个矩阵乘法,不是简单的A*B,而是AT*B
然后你可以从 Matrix Multiplication in pure Python? 中获取乘法代码,然后写

matrix_a = [[1, 1], [2, 1]]
#matrix_a = [[1, 2], [3, 4]]
matrix_b = [[25, 1.5], [30, 2.7]]

transposed_matrix_a =[list(i) for i in zip(*matrix_a)]
transposed_matrix_b =[list(i) for i in zip(*matrix_b)]

print([[sum(ele_a*ele_b for ele_a, ele_b in zip(row_a, col_b)) 
        for col_b in transposed_matrix_b] for row_a in transposed_matrix_a])

a,b,c,d=sum(matrix_a,[])
w,x,y,z=sum(matrix_b,[])
print(a*w+c*y,a*x+c*z)
print(b*w+d*y,b*x+d*z)

会产生

[[85, 6.9], [55, 4.2]]
85 6.9
55 4.2

(注释的 1,2,3,4 矩阵用于验证目的,因为原始矩阵内部有很多 1,某些索引问题可能会被忽视)