Skip to content

Numpy và Pandas

This content is not available in your language yet.

Sau bài này, bạn sẽ:

  • Hiểu rõ cấu trúc mảng đa chiều ndarray của NumPy, cơ chế lưu trữ bộ nhớ liên tục (contiguous memory) và sự khác biệt về hiệu năng so với danh sách Python thuần.
  • Làm chủ kỹ thuật tính toán vector hóa (Vectorization) và quy tắc mở rộng kích thước tự động (Broadcasting) để viết code đại số tuyến tính không cần vòng lặp.
  • Thành thạo thao tác với cấu trúc Series và DataFrame trong Pandas: truy xuất lát cắt với .loc và .iloc.
  • Xử lý dữ liệu bảng thực tế trong AI: phát hiện và xử lý giá trị khuyết (NaN), gom nhóm và tổng hợp dữ liệu với .groupby().

Tại sao chúng ta không thể dùng danh sách list của Python để huấn luyện mạng nơ-ron?

Hãy xem xét một ví dụ nhỏ: bạn muốn nhân một ma trận ảnh 1000×10001000 \times 1000 điểm ảnh với một ma trận trọng số.

  • Nếu dùng vòng lặp for lồng nhau trong Python thuần, chương trình phải thực hiện 1 tỷ phép tính nhân cộng. Mỗi phép tính, Python phải kiểm tra kiểu dữ liệu, giải mã con trỏ và cấp phát đối tượng mới. Quá trình này có thể mất tới hàng chục giây.
  • Với NumPy, toàn bộ khối dữ liệu 1 triệu con số được lưu trữ liền kề nhau dưới dạng các byte nhị phân trong bộ nhớ RAM. CPU chỉ cần một lệnh máy duy nhất để xử lý đồng thời cả một khối số (SIMD - Single Instruction, Multiple Data). Phép tính kết thúc chỉ trong vài phần nghìn giây!

NumPy đóng vai trò là “động cơ toán học” phía sau mọi thư viện Machine Learning và Deep Learning. Còn Pandas là “bàn làm việc dữ liệu” giúp bạn làm sạch, biến đổi và khám phá các tập dữ liệu thực tế trước khi đưa vào mô hình.

Mảng ndarray (N-dimensional array) là cấu trúc trung tâm của NumPy:

  • Tất cả các phần tử trong mảng phải có cùng một kiểu dữ liệu (đồng nhất - homogeneous, ví dụ toàn bộ là float32 hoặc int64).
  • Kích thước các chiều được mô tả qua thuộc tính .shape (tuple thể hiện số chiều).
  • Kiểu dữ liệu được lưu trong .dtype.

Vectorization là phương pháp diễn đạt các phép toán trên toàn bộ mảng cùng lúc thay vì lặp qua từng phần tử bằng vòng lặp for.

Thay vì viết:

# Cách chậm (Python for loop):
c = [a[i] * b[i] for i in range(len(a))]

Bạn chỉ cần viết:

# Cách vector hóa siêu tốc (NumPy C-speed):
c = a * b

Broadcasting cho phép NumPy thực hiện các phép toán số học giữa các mảng có kích thước khác nhau mà không cần tốn bộ nhớ sao chép dữ liệu.

Quy tắc phát sóng: Khi so khớp hai mảng, NumPy so sánh kích thước của từng chiều từ phải sang trái:

  1. Hai chiều bằng nhau: Hợp lệ.
  2. Một trong hai chiều bằng 1: Chiều đó sẽ được kéo giãn ảo để khớp với chiều còn lại.
  3. Nếu khác nhau và không có chiều nào bằng 1: Báo lỗi ValueError: operands could not be broadcast together.

Ví dụ: ma trận kích thước (4,3)(4, 3) cộng với vector (3,)(3,) sẽ tự động mở rộng vector thành (1,3)(1, 3), rồi phát sóng thành (4,3)(4, 3) để thực hiện phép cộng trên từng dòng.

Pandas: Phân Tích và Xử Lý Dữ Liệu Dạng Bảng

Phần tiêu đề “Pandas: Phân Tích và Xử Lý Dữ Liệu Dạng Bảng”

Pandas cung cấp hai cấu trúc dữ liệu thiết yếu:

  • Series: Mảng dữ liệu một chiều kèm theo nhãn chỉ mục (index).
  • DataFrame: Bảng dữ liệu hai chiều gồm nhiều dòng và cột (tương tự như một bảng tính Excel hay bảng SQL).

Để tránh nhầm lẫn và lỗi logic, Pandas phân định rõ ràng hai phương thức truy xuất:

  • df.loc[...]: Truy xuất dựa trên nhãn (label-based). Bạn truyền vào tên cột hoặc giá trị của index.
  • df.iloc[...]: Truy xuất dựa trên vị trí số nguyên (integer position-based) từ 0 đến n-1.
# Lấy dòng có index nhãn "HN" và cột "price":
val = df.loc["HN", "price"]
# Lấy dòng thứ 0 và cột thứ 2 theo thứ tự vật lý:
val = df.iloc[0, 2]

Trong thực tế, dữ liệu thu thập luôn có các giá trị bị khuyết (NaN - Not a Number hoặc None). Các thao tác cốt lõi:

  • df.isna().sum(): Đếm số lượng giá trị khuyết trên từng cột.
  • df.dropna(): Xóa bỏ các dòng hoặc cột có chứa giá trị khuyết.
  • df.fillna(value): Điền giá trị thay thế (ví dụ giá trị trung bình .mean() hoặc trung vị .median()).

Quy trình Split-Apply-Combine (Chia tách - Áp dụng - Gom lại) được thực hiện thông qua .groupby():

# Gom nhóm theo loại căn hộ và tính diện tích trung bình
df.groupby("type")["area"].mean()

Bạn cũng có thể dùng .agg() để tính toán đồng thời nhiều chỉ số thống kê trên các cột khác nhau trong một câu lệnh duy nhất.

Quy tắc mở rộng kích thước tự động (Broadcasting) trong NumPy:

Ma trận A (3 × 3): Vector B (1 × 3):
┌───┬───┬───┐ ┌───┬───┬───┐
│ 1 │ 2 │ 3 │ │ 10│ 20│ 30│
├───┼───┼───┤ └───┴───┴───┘
│ 4 │ 5 │ 6 │ + │ (Tự động phát sóng dọc theo 3 dòng)
├───┼───┼───┤ ▼
│ 7 │ 8 │ 9 │ ┌───┬───┬───┐
└───┴───┴───┘ │ 10│ 20│ 30│
├───┼───┼───┤
│ 10│ 20│ 30│
├───┼───┼───┤
│ 10│ 20│ 30│
└───┴───┴───┘

Quy trình Split-Apply-Combine của Pandas .groupby():

[ Dữ liệu thô ] ──► SPLIT (Tách nhóm theo chuyên mục: A, B)
├── Nhóm A ──► APPLY: Tính giá trị trung bình ──┐
└── Nhóm B ──► APPLY: Tính giá trị trung bình ──┴──► COMBINE: Ghép thành bảng tổng hợp

Các ô dưới đây chạy độc lập. Bạn có thể nhấn nút Chạy để xem ngay kết quả.

Ô thứ nhất ứng dụng NumPy để tính toán mô hình tuyến tính vector hóa: nhân ma trận đặc trưng X\mathbf{X} với trọng số w\mathbf{w}, cộng hệ số chệch bb bằng broadcasting, và tính sai số bình phương trung bình (MSE) chỉ trong vài dòng code:

Tính toán mô hình tuyến tính vector hóa với NumPy

import numpy as np
# Tạo ma trận đặc trưng X (4 mẫu, 2 đặc trưng) và nhãn y_true
X = np.array([[1.0, 2.0], [2.0, 1.0], [3.0, 4.0], [4.0, 3.0]])
y_true = np.array([5.0, 4.0, 11.0, 10.0])
# Khởi tạo vector trọng số w và hệ số chệch bias b
w = np.array([2.0, 1.0])
b = 0.5
# 1. Nhân ma trận vector hóa: y_hat = X @ w + b (kết hợp broadcasting)
y_hat = X @ w + b
# 2. Tính sai số toàn bộ tập dữ liệu trong một phép toán
errors = y_hat - y_true
mse = np.mean(errors ** 2)
print(f"Matrix X shape: {X.shape}")
print(f"Predictions y_hat: {y_hat}")
print(f"Sample errors: {np.round(errors, 3)}")
print(f"Mean Squared Error: {mse:.4f}")

The first run downloads Python, about 10 MB.

Mọi phép tính ma trận và thống kê sai số diễn ra tức thì mà không cần bất kỳ một vòng lặp for nào. Đây chính là cách các thuật toán Machine Learning xử lý hàng triệu điểm dữ liệu huấn luyện.

Ô thứ hai thể hiện các kỹ năng làm sạch và tổng hợp dữ liệu nhà đất với Pandas: xử lý giá trị khuyết bằng trung vị, lọc dòng bằng .loc, và tổng hợp thống kê bằng .groupby().

Tiền xử lý và gom nhóm thống kê với Pandas

import numpy as np
import pandas as pd
# Tập dữ liệu căn hộ mẫu chứa một giá trị khuyết (NaN)
data = {
"district": ["Quan 1", "Quan 1", "Quan 3", "Quan 3", "Quan 7"],
"area": [45.0, 70.0, 52.0, 85.0, 60.0],
"bedrooms": [1.0, np.nan, 2.0, 3.0, 2.0],
"price": [3.2, 5.8, 3.9, 6.5, 4.1],
}
df = pd.DataFrame(data)
# 1. Điền giá trị khuyết bằng trung vị (median) của thuộc tính
median_beds = df["bedrooms"].median()
df["bedrooms"] = df["bedrooms"].fillna(median_beds)
# 2. Lọc các căn hộ diện tích >= 60m2 bằng thuộc tính .loc
large_homes = df.loc[df["area"] >= 60.0, ["district", "area", "price"]]
# 3. Gom nhóm theo quận và tổng hợp giá trung bình cùng số lượng căn hộ
summary = df.groupby("district").agg(
avg_price=("price", "mean"),
count=("price", "count"),
).round(2)
print("Summary table by district:")
print(summary)

The first run downloads Python, about 10 MB.

Kết quả in ra bảng tổng hợp giá bán trung bình và số lượng giao dịch theo từng quận, cung cấp bức tranh dữ liệu tổng quan nhanh chóng và chính xác.

Question 1 of 4 Vì sao phép cộng hai mảng NumPy 1 000 000 phần tử lại nhanh hơn từ 50 đến 100 lần so với việc dùng vòng lặp for cộng hai list tương đương trong Python?
Question 2 of 4 Cho hai mảng AA có kích thước (4, 1) và BB có kích thước (3,). Kết quả của phép cộng broadcasting A + B sẽ có kích thước (shape) là gì?
Question 3 of 4 Cho một DataFrame df có chỉ mục tùy biến gồm các chuỗi: df.index = ["k1", "k2", "k3"]. Lệnh df.iloc[0] và df.loc["k1"] lần lượt trả về dòng dữ liệu nào?
Question 4 of 4 Phương pháp nào sau đây là cách chuẩn mực để điền các giá trị thiếu (NaN) của cột "age" bằng giá trị trung vị trong Pandas?

Ý chính:

  • ndarray của NumPy lưu trữ dữ liệu đồng nhất trên các ô nhớ liên tục trong C, mang lại tốc độ vượt trội nhờ cơ chế cache và SIMD.
  • Vectorization loại bỏ hoàn toàn các vòng lặp thủ công, giúp mã nguồn ngắn gọn, tối ưu và hạn chế lỗi.
  • Broadcasting mở rộng các mảng có kích thước tương thích mà không cần cấp phát thêm bộ nhớ vật lý.
  • Pandas cung cấp DataFrame và Series cho phép thao tác dữ liệu dạng bảng mạnh mẽ với .loc, .iloc, .fillna(), và .groupby().

Đọc thêm:

Content licensed under CC BY-NC-SA 4.0. Code under the MIT license.About