Tin tức và phân tích của tất cả các thiết bị di động

3 cách nhân ma trận trong python

Trong hướng dẫn này, bạn sẽ học cách nhân hai ma trận trong Python.

Bạn sẽ bắt đầu bằng cách tìm hiểu điều kiện để nhân ma trận thích hợp và viết một hàm Python tùy chỉnh để nhân ma trận. Sau đó, bạn sẽ thấy cách bạn có thể đạt được kết quả tương tự bằng cách sử dụng danh sách kết hợp lồng nhau.

Cuối cùng, bạn sẽ chuyển sang sử dụng NumPy và các hàm tích hợp của nó để thực hiện phép nhân ma trận hiệu quả hơn.

Làm cách nào để kiểm tra xem phép nhân ma trận có đúng không?

Trước khi chúng ta viết mã Python cho phép nhân ma trận, hãy xem những kiến ​​thức cơ bản về phép nhân ma trận.

Phép nhân ma trận giữa hai ma trận A và B chỉ hợp lệ nếu số cột trong A bằng số hàng trong B.

Có thể bạn đã từng gặp điều kiện nhân ma trận này trước đây. Tuy nhiên, có bao giờ bạn tự hỏi tại sao lại như vậy?

Chà, đó là do cách hoạt động của phép nhân ma trận. Nhìn vào hình ảnh dưới đây.

Trong ví dụ tổng quát của chúng ta, ma trận A có m hàng và m cột. Một ma trận B có n hàng và p cột.

Hình dạng của ma trận sản phẩm là gì?

Phần tử có chỉ số (i, j) trong ma trận kết quả C là tích vô hướng của hàng i của A và cột j của B.

Vì vậy, để lấy phần tử có chỉ số nhất định trong ma trận C kết quả, bạn cần tính tích vô hướng của hàng và cột tương ứng trong ma trận A và B tương ứng.

Bằng cách lặp lại quá trình trên, bạn sẽ nhận được một ma trận tích C có dạng mxp – với m hàng và p cột, như hình bên dưới.

Tích vô hướng hoặc tích vô hướng giữa hai vectơ a và b được cho bởi phương trình sau.

Bây giờ hãy tóm tắt:

  • Rõ ràng là tích vô hướng chỉ được xác định giữa các vectơ có độ dài bằng nhau.
  • Như vậy, để tích vô hướng giữa một hàng và một cột có giá trị khi nhân hai ma trận thì cả hai ma trận phải có cùng số phần tử.
  • Trong ví dụ tổng quát trên, mỗi hàng trong A có n phần tử. Và mỗi cột trong ma trận B cũng có n phần tử.

Nếu bạn nhìn kỹ, n là số cột trong ma trận A và cũng là số hàng trong ma trận B. Và đó là lý do tại sao bạn cần số cột trong ma trận A bằng số hàng trong ma trận B.

Hi vọng các bạn đã hiểu điều kiện để phép nhân ma trận hợp lệ và cách lấy từng phần tử trong ma trận tích.

Hãy chuyển sang viết mã Python sẽ nhân hai ma trận.

Viết hàm python tùy chỉnh để nhân ma trận

Bước đầu tiên, hãy viết một hàm nhân ma trận tùy chỉnh.

Chức năng này nên làm như sau:

  • Chấp nhận hai ma trận A và B làm đầu vào.
  • Xác minh rằng phép nhân ma trận giữa A và B là chính xác.
  • Nếu đúng, nhân hai ma trận A và B và trả về ma trận tích C.
  • Ngược lại, trả về lỗi không nhân được ma trận A và B.

Bươc 1: Tạo hai ma trận số nguyên bằng cách sử dụng hàm random.randint() của NumPy. Bạn cũng có thể khai báo ma trận dưới dạng danh sách lồng nhau của python.

import numpy as np
np.random.seed(27)
A = np.random.randint(1,10,size = (3,3))
B = np.random.randint(1,10,size = (3,2))
print(f"Matrix A:n {A}n")
print(f"Matrix B:n {B}n")

# Output
Matrix A:
 [[4 9 9]
 [9 1 6]
 [9 2 3]]

Matrix B:
 [[2 2]
 [5 7]
 [4 4]]

Bươc 2: Hãy tiếp tục và xác định hàm multi_matrix(A,B). Hàm này lấy hai ma trận A và B làm đầu vào và trả về ma trận tích C nếu phép nhân ma trận hợp lệ.

def multiply_matrix(A,B):
  global C
  if  A.shape[1] == B.shape[0]:
    C = np.zeros((A.shape[0],B.shape[1]),dtype = int)
    for row in range(rows): 
        for col in range(cols):
            for elt in range(len(B)):
              C[row, col] += A[row, elt] * B[elt, col]
    return C
  else:
    return "Sorry, cannot multiply A and B."

Phân tích định nghĩa hàm

Hãy chuyển sang phân tích các định nghĩa hàm.

Khai báo C dưới dạng biến toàn cục: Theo mặc định, tất cả các biến bên trong hàm Python đều có phạm vi cục bộ. Và bạn không thể truy cập chúng từ bên ngoài chức năng. Để làm cho ma trận tích C có thể truy cập được từ bên ngoài, chúng ta sẽ cần khai báo nó như một biến toàn cục. Chỉ cần thêm một vòng loại toàn cầu trước tên biến.

Kiểm tra xem phép nhân ma trận có hợp lệ không: Sử dụng thuộc tính shape để kiểm tra xem A và B có thể nhân được không.[0] và mảng.shape[1] chỉ định số hàng và số cột tương ứng. Vì vậy, nếu A.shape[1] == B.hình dạng[0] kiểm tra xem phép nhân ma trận có đúng không. Chỉ khi điều kiện này là Đúng, ma trận sản phẩm sẽ được tính toán. Nếu không, chức năng trả về một thông báo lỗi.

Sử dụng các vòng lặp lồng nhau để tính toán các giá trị: Để tính toán các phần tử của ma trận kết quả, chúng ta cần lặp qua các hàng của ma trận A và vòng lặp for bên ngoài sẽ thực hiện điều đó. Vòng lặp for bên trong giúp chúng ta lặp qua cột của ma trận B. Và vòng lặp for trong cùng giúp chúng ta truy cập đến từng phần tử trong cột đã chọn.

▶️ Bây giờ chúng ta đã học cách hoạt động của phép nhân ma trận trong Python, hãy gọi hàm với ma trận A và B mà chúng ta đã tạo trước đó.

multiply_matrix(A,B)

# Output
array([[ 89, 107],
       [ 47,  49],
       [ 40,  44]])

Vì phép nhân ma trận giữa A và B là hợp lệ, phép nhân_ma trận() trả về ma trận tích của C.

Sử dụng danh sách kết hợp lồng nhau trong python để nhân ma trận

Trong phần trước, bạn đã viết một hàm Python để nhân ma trận. Bây giờ bạn sẽ thấy cách bạn có thể sử dụng danh sách kết hợp lồng nhau để làm điều tương tự.

Đây là một danh sách kết hợp lồng nhau để nhân ma trận.

Điều này có vẻ phức tạp lúc đầu. Nhưng chúng tôi sẽ phân tích danh sách lồng nhau từng bước.

Mỗi lần hãy tập trung vào việc hiểu một danh sách và xác định chức năng của nó.

Chúng tôi sẽ sử dụng mẫu chung sau đây để hiểu danh sách:

[<do-this> for <item> in <iterable>]

where,
<do-this>: what you'd like to do—expression or operation
<item>: each item you'd like to perform the operation on
<iterable>: the iterable (list, tuple, etc.) that you're looping through

▶️ Hãy xem hướng dẫn Hiểu danh sách trong Python của chúng tôi – với các ví dụ để hiểu sâu hơn.

Trước khi chúng tôi tiếp tục, lưu ý rằng chúng tôi muốn xây dựng ma trận kết quả C một hàng tại một thời điểm.

Giải thích một danh sách lồng nhau với sự hiểu biết

Bươc 1: Tính một giá trị duy nhất trong ma trận C

Cho hàng i của ma trận A và cột j của ma trận B, biểu thức sau cho một mục tại chỉ mục (i, j) trong ma trận C.

sum(a*b for a,b in zip(A_row, B_col)

# zip(A_row, B_col) returns an iterator of tuples
# If A_row = [a1, a2, a3] & B_col = [b1, b2, b3]
# zip(A_row, B_col) returns (a1, b1), (a2, b2), and so on

Nếu tôi = j = 1biểu thức sẽ trả về mục c_11 của ma trận C. Bằng cách này, bạn có thể nhận được một phần tử trên mỗi hàng.

Bươc 2: Dựng một hàng trong ma trận C

Mục tiêu tiếp theo của chúng tôi là xây dựng toàn bộ hàng.

Trong trường hợp một bài thơ 1 trong ma trận A, bạn phải lặp qua tất cả các cột trong ma trận B để có được một hàng hoàn chỉnh trong ma trận C.

Quay lại mẫu danh sách đọc hiểu.

  • Thay thế bằng biểu thức từ bước 1bởi vì đó là những gì bạn muốn làm.
  • Sau đó thay thế bằng B_col – mọi cột trong ma trận B.
  • Cuối cùng thay thế bằng zip(*B) – một danh sách chứa tất cả các cột trong ma trận B.

Và đây là cách hiểu đầu tiên của danh sách.

[sum(a*b for a,b in zip(A_row, B_col)) for B_col in zip(*B)] 

# zip(*B): * is the unzipping operator
# zip(*B) returns a list of columns in matrix B

Bươc 3: Dựng tất cả các hàng và lấy ma trận C

Sau đó, bạn sẽ cần điền vào ma trận sản phẩm C bằng cách tính các hàng còn lại.

Để làm điều này, bạn cần lặp qua tất cả các hàng trong ma trận A.

Quay lại phần hiểu danh sách một lần nữa và làm như sau.

  • Thay thế bằng biểu thức danh sách từ bước 2. Nhớ lại rằng trong bước trước, chúng tôi đã tính toán toàn bộ hàng.
  • Bây giờ hãy thay thế bằng A_row – mọi hàng trong A.
  • Và của bạn chính là ma trận A khi bạn đi qua các hàng của nó.

Và đây là hiểu biết cuối cùng của chúng ta về danh sách lồng nhau.🎊

[[sum(a*b for a,b in zip(A_row, B_col)) for B_col in zip(*B)] 
    for A_row in A]

Thời gian để xác minh kết quả! ✔

# cast into <a href="https://newsblog.pl.com/numpy-reshape-arrays-in-python/">NumPy array</a> using np.array()
C = np.array([[sum(a*b for a,b in zip(A_row, B_col)) for B_col in zip(*B)] 
    for A_row in A])

# Output:
[[ 89 107]
 [ 47  49]
 [ 40  44]]

Nếu bạn nhìn kỹ, nó tương đương với các vòng lặp for lồng nhau mà chúng ta đã có trước đây – chỉ là nó ngắn gọn hơn.

Bạn có thể làm điều này thậm chí hiệu quả hơn bằng cách sử dụng một số tính năng tích hợp sẵn. Hãy cùng tìm hiểu về chúng trong phần tiếp theo.

Sử dụng NumPy matmul() để nhân ma trận trong Python

Ví dụ: matmul() lấy hai ma trận làm đầu vào và trả về kết quả nếu phép nhân ma trận giữa các ma trận đầu vào là hợp lệ.

C = np.matmul(A,B)
print(C)

# Output:
[[ 89 107]
 [ 47  49]
 [ 40  44]]

Lưu ý rằng phương pháp này đơn giản hơn hai phương pháp chúng ta đã học trước đó. Thực tế, thay vì np.matmul(), bạn có thể sử dụng toán tử @ tương đương và chúng ta sẽ thấy ngay.

Làm cách nào để sử dụng toán tử @ trong Python để nhân ma trận?

Trong Python, @ là một toán tử nhị phân được sử dụng để nhân ma trận.

Nó hoạt động trên hai ma trận và mảng N-chiều NumPy nói chung và trả về một ma trận tích.

Lưu ý: Bạn phải có Python để sử dụng toán tử @ 3.5 hoặc mới hơn.

Đây là cách bạn có thể sử dụng nó.

C = [email protected]
print(C)

# Output
array([[ 89, 107],
       [ 47,  49],
       [ 40,  44]])

Lưu ý rằng ma trận sản phẩm C giống như ma trận chúng ta có trước đó.

Bạn có thể sử dụng np.dot() để nhân ma trận không?

Nếu bạn đã từng gặp đoạn mã sử dụng np.dot() để nhân hai ma trận, thì đây là cách mã này hoạt động.

C = np.dot(A,B)
print(C)

# Output:
[[ 89 107]
 [ 47  49]
 [ 40  44]]

Bạn sẽ thấy rằng np.dot(A, B) cũng trả về ma trận tích mong đợi.

Tuy nhiên, theo tài liệu NumPy, bạn chỉ nên sử dụng np.dot() để tính tích vô hướng của hai vectơ một chiều, không phải cho phép nhân ma trận.

Nhớ lại phần trước, phần tử tại chỉ số (i, j) của ma trận tích C là tích vô hướng của hàng i của A và cột j của B.

Vì NumPy hoàn toàn phát hoạt động sản phẩm chấm này tới tất cả các hàng và tất cả các cột, nên bạn sẽ có được ma trận sản phẩm kết quả. Tuy nhiên, để giữ cho mã của bạn có thể đọc được và tránh sự mơ hồ, hãy sử dụng ví dụ: matmul() hoặc toán tử @ để thay thế.

Đăng kí

🎯 Trong hướng dẫn này, bạn đã học được những điều sau.

  • Điều kiện để phép nhân ma trận đúng: số cột của ma trận A = số hàng của ma trận B.
  • Cách viết hàm tùy chỉnh python để kiểm tra xem phép nhân ma trận có hợp lệ hay không và trả về ma trận tích. Phần thân của hàm sử dụng các vòng lặp for lồng nhau.
  • Tiếp theo, bạn đã học cách sử dụng danh sách ghép lồng nhau để nhân ma trận. Chúng ngắn gọn hơn các vòng lặp for, nhưng dễ gặp các vấn đề về khả năng đọc.
  • Cuối cùng, bạn đã học cách sử dụng hàm np.matmul() tích hợp sẵn của NumPy để nhân ma trận và cách sử dụng hàm này hiệu quả nhất xét về mặt tốc độ.
  • Bạn cũng đã học về toán tử @ để nhân hai ma trận trong Python.

Và điều đó kết thúc phần thảo luận của chúng ta về phép nhân ma trận trong Python. Trong bước tiếp theo, hãy tìm hiểu cách kiểm tra xem một số có phải là số nguyên tố hay không trong Python. Hoặc giải các bài toán thú vị trên chuỗi python.

Chúc bạn học tập vui vẻ!🎉