Trong toán học ma trận là một mảng chữ nhật, bao gồm các phần tử được sắp xếp theo hàng và cột. Với một ma trận người ta thường quy ước kích thước theo dạng m x n (số hàng x số cột). Ví dụ một ma trận có kích thước 2 x 3 (2 hàng 3 cột) bên dưới:

Các phần tử trong ma trận được truy cập theo A[i][j] trong đó i là chỉ số hàng và j là chỉ số cột. Ví dụ A[1][2] = 5, phần tử này tại vị trí dòng 1, cột 2. Trong bài hôm nay, chúng ta sẽ cũng học cách sử dụng ma trận trong Python.

1. Ma trận bằng LIST trong Python

Trong Python, không tồn tại kiểu dữ liệu cho ma trận. Tuy nhiên ta có thể biểu diễn một ma trận trong kiểu LIST. Biểu diễn ma trận trong LIST là việc khai báo các LIST có các phần tử cũng là một LIST. Điều này có nghĩa là phần tử của LIST cũng chính là một LIST.

Ví dụ ta khai báo một ma trận với List như sau:

# Khai bao ma tran 2 x 3
A = [[-2, 5, 6],
     [5, 2, 7]]

# Hien thi ma tran
print(A)

Kết quả:

[[-2, 5, 6], [5, 2, 7]]

Để truy cập vào một phần tử có trong ma trận, ta cần biết chỉ số hàng và chỉ số cột của phần tử đó. Ví dụ, tôi truy cập vào phần tử A[0][1] (i = 1, j = 2) sẽ như sau:

# Khai bao ma tran 2 x 3
A = [[-2, 5, 6],
     [5, 2, 7]]
     
# Truy cap vao phan tu tai vi tri hang 0, cot 1
x = A[0][1]

# Hien thi ma tran ket qua
print(x)

Kết quả:

5

Lưu ý rằng, chỉ số hàng và chỉ số cột của phần tử trong LIST luôn bắt đầu từ 0. Vì vậy ở kết quả trên, khi truy cập A[0][1] = 5

Để lấy ra một hàng trong ma trận, ta chỉ cần khai báo chỉ số hàng cần lấy mà không cần khai báo chỉ số cột. Ví dụ dưới đây lấy ra hàng thứ 0 trong ma trận:

# Khai bao ma tran 2 x 3
A = [[-2, 5, 6],
     [5, 2, 7]]
     
# Lay ra hang thu 0 trong ma tran
x = A[0]

# Hien thi ma tran ket qua
print(x)

Kết quả:

[-2, 5, 6]

Để thay đổi giá trị của một phần tử trong ma trận, ta cần truy cập theo hàng và cột của phần tử đó, sau đó sử dụng toán tử gán bằng “=” để gán giá trị mới cho phần tử cần thay đổi giá trị. Ví dụ thay đổi giá trị của phần tử A[0][1] bằng giá trị 10 như sau:

# Khai bao ma tran 2 x 3
A = [[-2, 5, 6],
     [5, 2, 7]]
     
# Truy cap vao phan tu tai vi tri hang 0, cot 1
x = A[0][1]

# Hien thi phan tu ban dau
print("A[0][1] ban: {0}".format(x))

# Thay doi gia tri phan tu A[0][1] bang 10
A[0][1] = 10

# Gan lai gia tri cua phan tu A[0][1]
y = A[0][1]

# Hien thi ket qua sau khi thay doi
print("A[0][1] sau khi thay doi: {0}".format(y))

Kết quả:

A[0][1] ban: 5
A[0][1] sau khi thay doi: 10

Để duyêt một ma trận, ta cần sử dụng vòng lặp for lồng nhau. Với lòng lặp for đầu tiên sẽ thực hiện duyệt qua từ hàng 0 đến hàng 1 của ma trận A. Vòng lặp for con nằm bên trong sẽ thực hiện duyệt qua từ cột 0 đến cột 2 của ma trận A.

# Khai bao ma tran 2 x 3
A = [[-2, 5, 6],
     [5, 2, 7]]

# Duyet qua tu hang 0 den 1     
for i in range(0,2):
    # Duyet qua tu cot 0 den 2
    for j in range(0,3):
        print(A[i][j],end="") # Hien thi phan tu tai dong i, cot j
    print() # Moi lan duyet xong hang se xuong dong

Kết quả:

-2 5 6
5 2 7

Trong mỗi lần duyệt qua các phần tử, ta có thể thực hiện một phép toán nào đó cho phần tử đang được duyệt. Ví dụ nhân tất cả các phần tử A[i][j] của ma trận A với số 2. Nghĩa là: A[i][j] * 2 trong mỗi lần duyệt.

# Khai bao ma tran 2 x 3
A = [[-2, 5, 6],
     [5, 2, 7]]
# Duyet qua tu hang 0 den 1     
for i in range(0,2):
    # Duyet qua tu cot 0 den 2
    for j in range(0,3):
        # Nhan phan tu tai dong i, cot j voi 2
        A[i][j] *= 2

# Hien thi lai ma tran sau khi nhan cac phan tu voi 2
print(A)

Kết quả:

[[-4, 10, 12], [10, 4, 14]]

2. Ma trận Numpy trong Python

2.1 Ma trận trong thư viện Numpy

Mô-đun Numpy được xây dựng để phục vụ chủ yếu cho việc thao tác và sử lý các con số. Trong đó hỗ trợ rất nhiều các hằng số, hàm số, ma trận, mảng…để phục vụ cho các chương trình liên quan đến toán học. Vì thư viện Numpy không có sẵn trong Python, nên để sử dụng được thư viện này ta cần thực hiện mở command line (CMD) và gõ câu lệnh cài đặt Numpy như sau:

pip install numpy

Sau khi cài đặt thư viện Numpy về máy thành công, để sử dụng được Numpy trong chương trình Python ta chỉ cần sử dụng câu lệnh import vào trong chương trình cần sử dụng như sau:

import numpy as np # dat ten np cho mô-đun numpy

Và tất nhiên, mô-đun Numpy cũng hỗ trợ thao tác với ma trận. Để tạo một ma trận trong Numpy ta có thể sử dụng hàm np.array. Ví dụ, tạo một ma trận có kích thước 1 x 3 trong Numpy bằng hàm np.array() như sau:

import numpy as np

# Khai bao mot ma tran 1 x 3
a = np.array([-2, 5, 6])

# Hien thi ma tran
print(a) 

# Kieu tra kieu du lieu cua ma tran 
print(type(a))

Kết quả:

[-2 5 6]
<class ‘numpy.ndarray’>

Lưu ý: Khi ma trận có kích thước 1 dòng, n cột thì ta có thể hiểu đây là một vectơ.

Ví dụ tiếp theo, khai báo một ma trận có kích thước 2 x 3 bằng cách sử dụng hàm np.array() như sau:

import numpy as np

# Khai bao mot ma tran 2 x 3
A = np.array([
    [-2, 5, 6],
    [5, 2, 7]]
    )

# Hien thi ma tran
print(A)

Kết quả:

[[-2 5 6]
[ 5 2 7]]

Để truy cập vào phần tử có trong ma trận Numpy, ta cũng chỉ cần thực hiện truy cập thông qua chỉ số hàng và chỉ số cột của phần tử đó. Ví dụ truy cập vào phần tử A[1][2] trong ma trận trên như sau:

import numpy as np
# Khai bao mot ma tran 2 x 3
A = np.array([
    [-2, 5, 6],
    [5, 2, 7]]
    )

# Truy cap phan tu tai hang 1 cot 2
x = A[1][2]

# Hien thi ket qua
print(x)

Lưu ý: Các phần tử trong ma trận thuộc Numpy cũng có chỉ số hàng và chỉ số cột bắt đầu từ 0.

2.2 Tạo ma trận zero và ma trận ones trong Numpy

Numpy hỗ trợ tạo nhanh một ma trận có kích thước m x n với các phần tử trong ma trận đều là số 0 bằng cách sử dụng hàm np.zeros() và tạo nhanh một ma trận có kích thước m x n với các phần tử trong ma trận đều là số 1 bằng cách sử dụng hàm np.ones()

import numpy as np

# Ma tran 2 x 3 cac phan tu la so 0
A = np.zeros((2, 3))
print(A)

print()

# Ma tran 2 x 3 cac phan tu la so 1
B = np.ones((2, 3))
print(B)

Kết quả:

[[0. 0. 0.]
 [0. 0. 0.]]

[[1. 1. 1.]
 [1. 1. 1.]]

2.3 Sử dụng arange() và shape() trong Numpy

Hàm arange() được sử dụng để tạo ra một ma trận mới trong một khoảng chỉ định trước. Ví dụ tạo một ma trận với các phần tử trong khoảng từ 5 đến 15 bằng hàm arange() như sau:

import numpy as np

# Tao mot ma tran co cac phan tu trong khoang 5 den 15
A = np.arange(5,16)

# Hien thi ket qua
print('A =', A)

Kết quả:

A = [ 5 6 7 8 9 10 11 12 13 14 15]

Hàm reshape() được sử dụng để chuyển đổi kích thước của một ma trận theo một con số cụ thế. Ví dụ dưới đây sử dụng hàm reshape() để chuyển đổi ma trận có kích thước 1 x 6 chuyển đổi sang ma trận có kích thước 2 x 3 như sau:

import numpy as np

# Tao ma tran co kich thuoc 1 x 6
A = np.array([1,2,3,4,5,6])

# Chuyen doi kich thuoc cua ma tran A
A = A.reshape(2,3)

# Hien thi ket qua
print(A)

Kết quả:

[[1 2 3]
[4 5 6]]

3. Phép toán trên ma trận Numpy

3.1 Chuyển vị ma trận Numpy

Ma trận chuyển vị là một ma trận AT của ma trận A. Khi đó, số dòng của ma trận A sẽ được chuyển thành số cột của ma trận AT và số cột của ma trận A sẽ được chuyển thành số dòng của ma trận AT

Ví dụ dưới đây, sử dụng hàm transpose() để tạo ra một ma trận chuyển vị của ma trận A trong Numpy:

import numpy as np

# Khai bao mot ma tran 2 x 3
A = np.array([
    [-2, 5, 6],
    [5, 2, 7]]
    )

# Hien thi ma tran A ban dau
print(A)

print()

# Ma tran chuyen vi cua ma tran A 
AT = A.transpose()

# Hien thi ma tran chuyen vi cua ma tran A
print(AT)

Kết quả:

[[-2  5  6]
 [ 5  2  7]]

[[-2  5]
 [ 5  2]
 [ 6  7]]

Lưu ý: Khi một ma trận có kích thước m x n được chuyển vị, khi đó ma trận chuyển vị sẽ có kích thước n x m.

3.2 Phép cộng giữa hai ma trận

Nếu như có hai ma trận có cùng kích thước, ta có thể cộng hai ma trận này lại với nhau theo cách cộng từng phần tử tương ứng của 2 ma trận cùng cấp với nhau.

import numpy as np

# Khai bao ma tran A kich thuoc 3 x 2
A = np.array([
    [2, 4, 6], 
    [5, 8, -3]
    ])

# Khai bao ma tran B kich thuoc 3 x 2
B = np.array([
    [2, 1, 5], 
    [3, 6, 9],
    ])

# Ket qua phep cong ma tran A voi ma tran B gan vao C
C = A + B 

# Hien thi ma tran sau khi thuc hien A + B
print(C)

Kết quả:

[[ 4 5 11]
[ 8 14 6]]

3.2 Phép nhân giữa 2 ma trận

Hai ma trận chỉ được phép thực hiện phép nhân khi và chỉ khi kích thước cột của ma trận A bằng với kích thước hàng của ma trận B. Điều này nghĩa là, A có kích thước n x m và B phải có kích thước m x n thì mới có thể thực hiện phép nhân hai ma trận. Kết quả của phép nhân 2 ma trận sẽ tạo ra ma trận mới có kích thước m x n

Nhân 2 ma trận là phép lấy tổng của tích từng phần tử của hàng tương ứng với cột tương ứng. Để nhân hai ma trận ta sẽ sử dụng hàm dot() như sau:

import numpy as np

# Khai bao ma tran A co kich thuoc 2 x 3
A = np.array([
    [3, 6, 7], 
    [5, -3, 0]
    ])

# Khai bao ma tran B co kich thuoc 3 x 2
B = np.array([
    [1, 1], 
    [2, 1], 
    [3, -3]
    ])

# Thuc hien phep nhan ma tran A voi ma tran B bang ham dot()
C = A.dot(B)

# Hien thi ma tran sau khi A.dot(B)
print(C)

Kết quả:

[[ 36 -12]
[ -1 2]]