
NumPy là gì và vì sao pandas cần NumPy
AIDev TeamTham vấn chuyên môn: Nguyễn Việt Chung
Đăng 11 phút đọc
Mục lục · 18
NumPy là gì? Đó là library Python lưu số trong mảng cùng kiểu và tính trên cả mảng một lúc, nên nhanh hơn list nhiều lần. Bài so list với mảng NumPy bằng số đo thật ở bốn cỡ dữ liệu, tính doanh thu tám chi nhánh bằng vài dòng code và chỉ ra chỗ pandas dùng NumPy.
NumPy là library (thư viện code viết sẵn) của Python để lưu và tính toán trên mảng số. Khác với list, mảng NumPy chỉ chứa một kiểu dữ liệu và mọi phép tính chạy trên cả mảng một lúc bằng code đã biên dịch sẵn, nên nhanh hơn vòng for của Python hàng chục lần. pandas lưu các cột số bằng mảng NumPy, vì vậy hiểu NumPy giúp bạn hiểu vì sao pandas nhanh và vì sao nó báo lỗi kiểu dữ liệu.
Mấy điều cần nắm trước khi đọc tiếp:
Đối tượng chính của NumPy là
ndarray, mảng n chiều. Mảng một chiều giống một dãy số, mảng hai chiều giống một bảng.Trên máy ảo AIDev Cloud, phép nhân 1 triệu số với 2 bằng NumPy mất 0,76 mili giây, bằng list mất 53,3 mili giây.
Cùng 1 triệu số nguyên, list chiếm 36,0 MB RAM, mảng NumPy chiếm 8,0 MB.
Lệnh
pip install pandastự cài NumPy. Bản mới nhất trên PyPI ngày 08/11/2026 là NumPy 2.5.4.
NumPy là gì và ra đời từ đâu?
Theo trang giới thiệu của NumPy (đọc ngày 08/11/2026), NumPy ra đời năm 2005, xây tiếp trên hai library cũ hơn là Numeric và Numarray, người sáng lập là Travis Oliphant. NumPy là mã nguồn mở theo giấy phép BSD bản sửa đổi, ai cũng dùng miễn phí được.
Tài liệu chính thức gọi NumPy là package nền tảng cho tính toán khoa học trong Python. Trong thực tế, phần lớn library dữ liệu và AI phổ biến đều nhận hoặc trả về mảng NumPy: pandas, scikit-learn, matplotlib, và cả PyTorch khi chuyển dữ liệu qua lại. Bạn hiếm khi viết cả một project chỉ bằng NumPy, nhưng gần như project dữ liệu nào cũng có NumPy chạy bên dưới.
Mảng NumPy đầu tiên trông thế nào?
Dataset của khóa Phân tích dữ liệu với Python (tải ở lab.aidev.edu.vn/k2) có file doanh_thu_chi_nhanh.csv: doanh thu 12 tháng năm 2025 của tám chi nhánh trong một chuỗi cửa hàng mô phỏng, đơn vị triệu đồng. Dòng đầu file là tên tám chi nhánh, skiprows=1 bỏ qua dòng đó. File không có cột tháng, dòng thứ i là tháng thứ i, nên đọc thẳng thành một mảng 12 × 8:
import numpy as np
dt = np.loadtxt("doanh_thu_chi_nhanh.csv", delimiter=",", skiprows=1)
print(type(dt).__name__, dt.shape, dt.dtype, dt.ndim)
print(dt[:3])
print("tổng theo chi nhánh (axis=0):", dt.sum(axis=0))
print("tổng theo tháng (axis=1):", dt.sum(axis=1))
print("tháng cao nhất của mỗi chi nhánh:", dt.argmax(axis=0) + 1)
print("số ô > 1000 triệu:", (dt > 1000).sum())
print("tăng trưởng tháng 12 so tháng 1 (%):", ((dt[11] / dt[0] - 1) * 100).round(1))

Dòng đầu in ba thuộc tính của mảng:
shapelà(12, 8): 12 dòng, 8 cột.dtypelàfloat64: mọi ô đều là số thực 64 bit, vìloadtxtmặc định đọc ra số thực.ndimlà 2: mảng hai chiều.
Tham số axis là chỗ người mới hay nhầm. axis=0 tính dọc theo các dòng, nên ra một số cho mỗi cột (mỗi chi nhánh). axis=1 tính ngang theo các cột, nên ra một số cho mỗi dòng (mỗi tháng). Chi nhánh Bến Thành (cột thứ năm trong file) có tổng cao nhất, 9.036 triệu đồng. argmax(axis=0) trả về vị trí của giá trị lớn nhất trong mỗi cột, cộng thêm 1 để ra số tháng. Bảy chi nhánh đạt đỉnh vào tháng 12, riêng Bến Thành đạt đỉnh vào tháng 1 và là chi nhánh duy nhất có tháng 12 thấp hơn tháng 1 (giảm 1,4%).
Dòng (dt > 1000).sum() cho thấy một cách viết quen thuộc trong NumPy: phép so sánh tạo ra một mảng True/False cùng cỡ, rồi sum() đếm số ô True. Ở đây không ô nào vượt 1.000 triệu đồng.
Mảng NumPy khác gì list trong Python?
Cùng một phép toán, list và mảng NumPy cho ra kết quả khác hẳn nhau. Đây là chỗ đáng chạy thử trước khi đọc tiếp:
import numpy as np
a, b = [1, 2, 3], [10, 20, 30]
print("list + list:", a + b)
print("list * 2 :", a * 2)
x, y = np.array(a), np.array(b)
print("array + array:", x + y)
print("array * 2 :", x * 2)

Với list, dấu + nối hai list, dấu * 2 lặp list hai lần. Với mảng NumPy, hai phép đó tính trên từng phần tử. Bảng dưới gom các điểm khác nhau mình thấy khi chạy:
Điểm so sánh | list Python | mảng NumPy |
|---|---|---|
Kiểu phần tử | trộn được số, chữ, list con | một kiểu cho cả mảng ( |
| nối, lặp list | cộng, nhân từng phần tử |
Thêm phần tử |
| cỡ cố định, |
1 triệu số nguyên | 36,0 MB | 8,0 MB |
Nhân 1 triệu số với 2 | 53,3 ms | 0,76 ms |
Script trong ảnh chạy thêm ba lệnh ngoài đoạn code trên: hai lệnh in ra dòng trộn kiểu và int8 tràn số, lệnh cuối gây lỗi broadcast (nói ở mục lỗi bên dưới). Hai dòng đầu là hai cái bẫy. np.array([1, "2", 3.5]) không báo lỗi mà đổi cả mảng sang chữ (kiểu <U32), nên phép cộng sau đó sẽ hỏng. Kiểu int8 chỉ chứa được số từ -128 đến 127, và 120 + 10 ra -126 mà không có cảnh báo nào. Với kiểu int64 mặc định thì phải tới số rất lớn mới tràn, nhưng khi bạn chủ động chọn kiểu nhỏ để tiết kiệm RAM thì nên nhớ giới hạn này.
NumPy nhanh hơn list bao nhiêu?
Mình đo hai phép tính ở bốn cỡ dữ liệu: cộng tất cả phần tử (sum) và nhân mọi phần tử với 2. Mỗi phép chạy năm lần và lấy trung vị (giá trị đứng giữa khi xếp từ nhỏ đến lớn). Hai bên chứa cùng các số: list tạo bằng list(range(n)), mảng tạo bằng np.arange(n). Đoạn chính của script, trong đó do là hàm chạy một phép năm lần rồi trả về trung vị:
t_sum_l, t_sum_a = do(lambda: sum(ds)), do(lambda: mang.sum())
t_nhan_l, t_nhan_a = do(lambda: [x * 2 for x in ds]), do(lambda: mang * 2)

Số phần tử |
| Nhanh hơn | Nhân 2: list / NumPy | Nhanh hơn |
|---|---|---|---|---|
1.000 | 0,008 / 0,002 ms | 5,0 lần | 0,037 / 0,005 ms | 6,7 lần |
100.000 | 0,868 / 0,028 ms | 31,0 lần | 4,727 / 0,077 ms | 61,4 lần |
1.000.000 | 8,668 / 0,262 ms | 33,0 lần | 53,289 / 0,756 ms | 70,5 lần |
10.000.000 | 88,734 / 5,789 ms | 15,3 lần | 601,778 / 25,930 ms | 23,2 lần |
Với 1.000 số, cả hai cách đều xong dưới 0,04 mili giây, chênh lệch không đáng để ý. Từ 100.000 số trở lên, NumPy nhanh hơn vài chục lần. Ở 10 triệu số, tỉ lệ giảm còn khoảng 15 đến 23 lần. Mình đoán nguyên nhân là mảng 80 MB không còn nằm gọn trong bộ nhớ đệm của CPU, nên NumPy cũng phải chờ RAM, nhưng mình chưa đo riêng để khẳng định.

List tốn RAM hơn vì mỗi phần tử là một đối tượng Python riêng (28 byte với số nguyên nhỏ) cộng thêm 8 byte cho con trỏ (địa chỉ trỏ tới đối tượng đó) nằm trong list. Mảng int64 chỉ cần đúng 8 byte cho mỗi số, xếp liền nhau trong bộ nhớ.
Vì sao pandas cần NumPy?
pandas lưu mỗi cột số của DataFrame (bảng dữ liệu của pandas) bằng một mảng NumPy. Mình kiểm tra trên 6.000 đơn hàng của cửa hàng mẫu Tiệm Mây (file don_hang_sach.csv trong cùng dataset):
import numpy as np
import pandas as pd
df = pd.read_csv("don_hang_sach.csv")
dt = df["doanh_thu"]
arr = dt.to_numpy()
print("cột doanh_thu:", dt.dtype, "->", type(arr).__name__, arr.dtype)
print("cột kenh :", df["kenh"].dtype, "->", type(df["kenh"].array).__name__)
print("dt.sum() =", dt.sum(), "| np.sum(arr) =", np.sum(arr))
print("np.log10 trên Series ->", type(np.log10(dt)).__name__)

Kết quả cho thấy ba điều:
Cột
doanh_thukiểuint64lấy ra bằngto_numpy()là mộtndarraycùng kiểu.dt.sum()vànp.sum(arr)cho cùng con số 17.753.491.000.Hàm của NumPy chạy thẳng trên Series (một cột của DataFrame):
np.log10(dt)trả về một Series, giữ nguyên index (nhãn của từng dòng).Cột chữ thì khác. Ở pandas 3, cột
kenhcó kiểustrvà nằm trongStringArray, một kiểu mảng riêng của pandas (máy mình chưa cài pyarrow; có pyarrow thì pandas dùngArrowStringArray). Đây là một trong các thay đổi lớn của pandas 3, bài pandas là gì có so trực tiếp với pandas 2.
Vì cột số là mảng NumPy, phép df["so_luong"] * df["don_gia"] nhân 6.000 cặp số trong một lần gọi, không có vòng for nào của Python. Mình kiểm tra lại: tích hai cột bằng cột doanh_thu ở cả 6.000 dòng.
Cài NumPy thế nào?
Nếu đã cài pandas thì bạn đã có NumPy. Muốn cài riêng, chạy pip install numpy trong virtual environment (môi trường Python riêng cho từng thư mục làm việc). NumPy 2.5.4 cần Python từ 3.12 trở lên theo PyPI. Kiểm tra phiên bản bằng:
python -c "import numpy; print(numpy.__version__)"
Khi chạy pip install pandas trên máy ảo Ubuntu 24.04 của AIDev Cloud, pip kéo theo NumPy 2.5.4 (file tải về 16,7 MB). Nếu gặp lỗi No module named numpy, nguyên nhân thường giống hệt lỗi với pandas: package đã vào một bản Python khác. Bài cài pandas và sửa lỗi No module named pandas có cách kiểm tra code đang chạy bằng bản Python nào.
Lỗi mình gặp khi dùng NumPy
Mảng NumPy không có append
Quen tay với list, mình gọi append trên mảng và nhận lỗi:
AttributeError: 'numpy.ndarray' object has no attribute 'append'

Mảng NumPy có cỡ cố định. np.append(gia, 658000) không sửa gia mà tạo một mảng mới, nên phải gán lại: gia = np.append(gia, 658000). Nếu cần thêm phần tử nhiều lần trong vòng lặp, cách nhanh hơn là gom vào list trước, cuối cùng mới đổi sang mảng bằng np.array(ds) một lần.
Hai mảng khác cỡ: lỗi broadcast
Cộng mảng ba phần tử với mảng hai phần tử thì NumPy dừng ngay:
ValueError: operands could not be broadcast together with shapes (3,) (2,)
Broadcast là quy tắc NumPy dùng để tính trên hai mảng khác cỡ, ví dụ cộng một số vào cả mảng, hay cộng một dòng 8 số vào từng dòng của bảng 12 × 8. Quy tắc này chỉ chạy khi các chiều khớp nhau hoặc một bên có cỡ 1. Khi gặp lỗi này, hãy in .shape của hai mảng ra trước. Thường thì một mảng đã bị lọc mất vài phần tử ở bước trước đó.
Khi nào không nên dùng NumPy?
Dữ liệu ít, vài trăm phần tử, lại hay thêm bớt phần tử: list đơn giản hơn và chênh lệch tốc độ không đáng kể (với 1.000 số, cả hai đều dưới 0,04 mili giây).
Bảng có tên cột, cột chữ, ngày tháng: dùng pandas, đừng tự quản lý mảng NumPy theo số thứ tự cột.
Dữ liệu trộn nhiều kiểu trong cùng một dãy, như bản ghi khách hàng: NumPy sẽ ép tất cả về một kiểu, thường là chữ.
Câu hỏi thường gặp
NumPy có phải là một ngôn ngữ riêng không?
Không. NumPy là một library của Python, bạn viết code Python bình thường và gọi các hàm của NumPy. Phần tính toán bên trong chạy bằng code đã biên dịch sẵn (chủ yếu viết bằng C), nên nhanh hơn vòng lặp Python.
Học NumPy trước hay pandas trước?
Biết NumPy là gì ở mức như bài này là đủ để bắt đầu. Nếu mục tiêu là phân tích dữ liệu dạng bảng, bạn có thể học pandas trước và học NumPy song song khi cần. Tuy vậy, nắm shape, dtype, axis và cách tính trên cả mảng giúp bạn đọc lỗi của pandas dễ hơn nhiều. Nếu đi tiếp sang machine learning, NumPy là bắt buộc vì dữ liệu đưa vào model đều là mảng.
np là gì trong code Python?
np là tên viết tắt khi nạp NumPy bằng import numpy as np. Đây chỉ là quy ước, nhưng gần như mọi tài liệu đều dùng, nên bạn nên viết theo để code dễ đọc.
ndarray là gì?
ndarray (n-dimensional array) là kiểu mảng n chiều của NumPy. np.array(...), np.arange(...) hay np.loadtxt(...) đều trả về một ndarray.
Đọc tiếp
pandas là gì? DataFrame và 10 dòng code đầu: bước tiếp theo sau NumPy, làm việc với bảng có tên cột trên cùng dataset Tiệm Mây.
Học Python từ số 0: nếu bạn chưa quen với list, vòng
forvà hàm.Data Analyst cần học gì: NumPy và pandas nằm ở đâu trong bộ kỹ năng phân tích dữ liệu.
Chương 1 của ebook Phân tích dữ liệu với Python là NumPy và tư duy vector, dùng chính file doanh thu tám chi nhánh trong bài này, trước khi sang pandas ở các chương sau. Sách có 89 bài tập tự chấm. Nếu bạn học dữ liệu để đi tiếp sang AI, lộ trình AI Engineer từ số 0 đi từ Python, qua phân tích dữ liệu, đến machine learning.
Code chạy ngày 26/10/2026 trên máy ảo AIDev Cloud: Ubuntu 24.04.4, Intel Xeon E5-2696 v4 25 vCPU, 54 GiB RAM, Python 3.12.3, NumPy 2.5.4, pandas 3.1.0. Dữ liệu doanh thu chi nhánh và Tiệm Mây là dữ liệu mô phỏng của AIDev (giấy phép MIT).
Chuyên mục
Phân tích dữ liệuTham vấn chuyên môn
Nhà sáng lập AIDev và VietPlatform · Thạc sĩ AI MSE
- Tốt nghiệp thủ khoa xuất sắc Thạc sĩ AI MSE.
- Đồng sáng lập, CTO E-University, SVOnline: số hóa 10+ đại học, 40.000+ sinh viên.
- Xây hệ thống AI cho doanh nghiệp tại VietPlatform.


