Pandas 3.0 trong 2026: API Mới, Breaking Changes và Câu Hỏi Phỏng Vấn
Hướng dẫn chi tiết về Pandas 3.0 bao gồm Copy-on-Write, PyArrow string backend, biểu thức pd.col(), breaking changes và câu hỏi phỏng vấn data analytics.

Pandas 3.0, được phát hành ngày 21 tháng 1 năm 2026, giới thiệu những thay đổi kiến trúc đáng kể nhất kể từ phiên bản 1.x của thư viện. Copy-on-Write trở thành hành vi mặc định, cột string chuyển sang dtype dựa trên PyArrow, và expression builder pd.col() mới cung cấp giải pháp thay thế sạch hơn cho hàm lambda. Những thay đổi này ảnh hưởng đến mọi codebase hiện có và ngày càng được kiểm tra trong các cuộc phỏng vấn data engineering.
Pandas 3.0 yêu cầu Python 3.11+, áp dụng ngữ nghĩa Copy-on-Write theo mặc định, và suy luận cột string là dtype str được hỗ trợ bởi PyArrow. Chained assignment giờ đây phát sinh lỗi thay vì warning.
Copy-on-Write: Kết Thúc Kỷ Nguyên SettingWithCopyWarning
Copy-on-Write (CoW) thay đổi căn bản cách pandas xử lý việc chia sẻ bộ nhớ giữa các DataFrame. Mọi thao tác indexing giờ đây trả về kết quả hoạt động như một bản sao, nhưng bên trong pandas vẫn chia sẻ bộ nhớ cho đến khi một thay đổi thực sự xảy ra.
Tác động thực tế: SettingWithCopyWarning không còn tồn tại. Các mẫu chained assignment như df[df['A'] > 0]['B'] = 1 giờ đây phát sinh ChainedAssignmentError vì kết quả indexing trung gian là một bản sao.
# migration_cow.py
import pandas as pd
df = pd.DataFrame({"price": [100, 200, 300], "category": ["A", "B", "A"]})
# Mẫu Pandas 2.x (giờ phát sinh ChainedAssignmentError)
# df[df["category"] == "A"]["price"] = 150 # HỎNG trong 3.0
# Mẫu đúng Pandas 3.0: sử dụng .loc[]
df.loc[df["category"] == "A", "price"] = 150
# Chia sẻ bộ nhớ CoW trong thực tế
df2 = df[["price"]] # chia sẻ bộ nhớ với df
df2["price"] = df2["price"] * 2 # bản sao chỉ được tạo ở đây
# df không thay đổi - không có tác dụng phụTham số keyword copy trên toàn bộ các method không còn có hiệu lực và có thể được xóa an toàn khỏi code hiện tại. Các method hỗ trợ inplace=True (replace(), fillna(), ffill(), bfill(), clip()) giờ trả về self thay vì None, cho phép method chaining ngay cả với thao tác in-place.
PyArrow String Backend: Thao Tác String Nhanh Hơn 5-10 Lần
Pandas 3.0 suy luận cột string là dtype str chuyên biệt được hỗ trợ bởi Apache Arrow, thay thế dtype object cũ. Nếu PyArrow không được cài đặt, phương án dự phòng sử dụng mảng đối tượng NumPy.
Hiệu suất được cải thiện đáng kể: .str.contains(), .str.lower(), và các method string khác chạy nhanh hơn 5-10 lần. Mức tiêu thụ bộ nhớ cho các cột chứa nhiều văn bản giảm đến 50%. Định dạng columnar của Arrow cũng cho phép trao đổi dữ liệu zero-copy với Polars, DuckDB và các công cụ dựa trên Arrow khác.
# string_dtype_comparison.py
import pandas as pd
import numpy as np
# Pandas 3.0: cột string tự động là str[pyarrow]
df = pd.DataFrame({"name": ["Alice", "Bob", "Charlie", None]})
print(df.dtypes)
# name string[pyarrow]
# dtype: object
# Giá trị thiếu sử dụng NaN (không phải pd.NA), phù hợp với các dtype mặc định khác
print(df["name"].isna()) # True cho mục None
# Tương tác trực tiếp với DuckDB (zero-copy)
import duckdb
result = duckdb.sql("SELECT name FROM df WHERE name LIKE '%li%'").df()Một ràng buộc quan trọng: mảng PyArrow là immutable. Việc chuyển đổi cột dựa trên PyArrow sang mảng NumPy có thể ghi yêu cầu bản sao tường minh thông qua .to_numpy(copy=True).
Code kiểm tra df['col'].dtype == object để phát hiện string sẽ bị lỗi. Thay thế bằng pd.api.types.is_string_dtype(df['col']) hoặc kiểm tra pd.StringDtype().
Expression Builder pd.col()
Pandas 3.0 giới thiệu pd.col() như một cách khai báo để tham chiếu cột DataFrame và xây dựng biểu thức. Cú pháp lấy cảm hứng từ PySpark và Polars, giải quyết các vấn đề đã biết với lambda scoping và tính opaque.
# col_expressions.py
import pandas as pd
df = pd.DataFrame({
"revenue": [1000, 2500, 800, 3200],
"cost": [400, 1200, 600, 1500],
"region": ["US", "EU", "US", "APAC"]
})
# Trước: dựa trên lambda (opaque, vấn đề scoping trong vòng lặp)
df = df.assign(profit=lambda x: x["revenue"] - x["cost"])
# Sau: pd.col() (khai báo, có thể kiểm tra)
df = df.assign(
profit=pd.col("revenue") - pd.col("cost"),
margin=((pd.col("revenue") - pd.col("cost")) / pd.col("revenue") * 100)
)
# Lọc với pd.col()
high_margin = df.loc[pd.col("margin") > 50]Ưu điểm chính so với lambda xuất hiện trong vòng lặp, nơi mà closure của lambda bắt biến theo tham chiếu và tạo ra kết quả sai:
# loop_scoping_fix.py
import pandas as pd
df = pd.DataFrame({"base": [10, 20, 30]})
# Lỗi lambda: tất cả cột sử dụng factor=30 (giá trị vòng lặp cuối)
# cols = {}
# for factor in [2, 5, 10]:
# cols[f"x{factor}"] = lambda x: x["base"] * factor # LỖI
# Sửa bằng pd.col(): mỗi biểu thức bắt giá trị đúng
cols = {}
for factor in [2, 5, 10]:
cols[f"x{factor}"] = pd.col("base") * factor # Đúng
df = df.assign(**cols)Tính đến pandas 3.0.2, pd.col() cũng hoạt động trong Series.case_when(). Tổng hợp groupby chưa được hỗ trợ.
Sẵn sàng chinh phục phỏng vấn Data Analytics?
Luyện tập với mô phỏng tương tác, flashcards và bài kiểm tra kỹ thuật.
Breaking Changes: Danh Sách Kiểm Tra Di Chuyển Đầy Đủ
Bảng sau tóm tắt các breaking changes có khả năng xuất hiện nhất trong quá trình di chuyển từ pandas 2.x:
| Thay Đổi | Hành Vi Pandas 2.x | Hành Vi Pandas 3.0 | Cách Sửa |
|----------|---------------------|---------------------|----------|
| Chained assignment | SettingWithCopyWarning | ChainedAssignmentError | Sử dụng .loc[] |
| String dtype | object | string[pyarrow] | Cập nhật kiểm tra dtype |
| Keyword copy= | Tạo bản sao | Không có hiệu lực (deprecated) | Xóa tham số |
| groupby(observed=) | Mặc định False | Mặc định True | Đặt tường minh |
| Index.sort_values() | Tham số vị trí được phép | Chỉ keyword | Đặt tên tất cả tham số |
| offsets.Day | Khoảng 24h cố định | Calendar-day (DST-aware) | Xem lại logic timezone |
| Categorical.map(na_action=) | Mặc định None | Mặc định thay đổi | Đặt tường minh |
| str.contains(na=) | Chấp nhận non-bool | Chỉ bool hoặc None | Dọn tham số na |
Lộ trình nâng cấp được khuyến nghị: đầu tiên nâng cấp lên pandas 2.3, giải quyết tất cả deprecation warning, sau đó chuyển sang 3.0.
Chính Sách Deprecation Mới: Pandas4Warning và Pandas5Warning
Pandas 3.0 giới thiệu chu kỳ deprecation 3 giai đoạn có cấu trúc. Các tính năng đầu tiên phát ra DeprecationWarning tiêu chuẩn, sau đó chuyển sang FutureWarning trong bản phát hành minor cuối cùng trước major tiếp theo, và cuối cùng bị loại bỏ trong bản phát hành major.
Hai lớp warning mới giúp lọc warning theo phiên bản mục tiêu dễ dàng hơn:
# filter_warnings.py
import warnings
import pandas as pd
# Chỉ bắt các thay đổi sẽ đến trong pandas 4.0
warnings.filterwarnings("error", category=pd.errors.Pandas4Warning)
# Bắt các thay đổi sẽ đến trong pandas 5.0
warnings.filterwarnings("default", category=pd.errors.Pandas5Warning)Chính sách này cho các maintainer thư viện ít nhất hai chu kỳ phát hành minor để thích ứng trước khi breaking changes được áp dụng.
Pandas 3.0 yêu cầu Python 3.11 hoặc cao hơn. Các dự án vẫn đang dùng Python 3.9 hoặc 3.10 phải nâng cấp trước khi di chuyển.
Câu Hỏi Phỏng Vấn: Deep Dive Pandas 3.0
Các câu hỏi sau xuất hiện trong các cuộc phỏng vấn data engineering và analytics năm 2026, kiểm tra cả hiểu biết lý thuyết và kinh nghiệm di chuyển thực tế.
Q1: Giải thích Copy-on-Write trong pandas 3.0. Tại sao nó được giới thiệu?
CoW đảm bảo rằng mọi DataFrame hoặc Series được trả về từ thao tác indexing hoạt động như một bản sao độc lập. Bên trong, pandas chia sẻ bộ nhớ giữa bản gốc và kết quả cho đến khi một trong số đó bị thay đổi, lúc đó một bản sao vật lý mới xảy ra. Điều này loại bỏ sự mơ hồ giữa view và copy đã gây ra SettingWithCopyWarning, ngăn chặn hư hỏng dữ liệu vô tình qua tác dụng phụ, và giảm sử dụng bộ nhớ cho các tải trọng đọc nhiều.
Q2: Điều gì xảy ra với df[condition]['col'] = value trong pandas 3.0?
Nó phát sinh ChainedAssignmentError. df[condition] trung gian giờ luôn là một bản sao (do CoW), nên việc gán giá trị vào cột trên bản sao đó không ảnh hưởng đến DataFrame gốc. Mẫu đúng là df.loc[condition, 'col'] = value.
Q3: Dtype string mới ảnh hưởng đến khả năng tương tác với các công cụ khác như thế nào?
Dtype string dựa trên PyArrow lưu trữ dữ liệu theo định dạng columnar của Apache Arrow. Điều này cho phép truyền dữ liệu zero-copy đến các công cụ dựa trên Arrow khác (Polars, DuckDB, Spark qua PyArrow) mà không có overhead serialization. Nó cũng giảm dấu chân bộ nhớ so với mảng đối tượng Python, vì Arrow sử dụng buffer nhị phân compact thay vì các đối tượng string Python riêng lẻ.
Q4: Vấn đề nào pd.col() giải quyết mà lambda không thể?
pd.col() bắt tham chiếu cột và giá trị tại thời điểm tạo biểu thức, không phải tại thời điểm thực thi. Lambda trong Python bắt biến theo tham chiếu, gây ra lỗi trong vòng lặp khi tất cả lambda cuối cùng tham chiếu đến biến vòng lặp cuối. Ngoài ra, biểu thức pd.col() có thể được kiểm tra (pandas có thể tối ưu hóa chúng), trong khi lambda là callable opaque.
Q5: Làm thế nào để di chuyển codebase từ pandas 2.x sang 3.0?
Bước 1: Nâng cấp lên pandas 2.3 và sửa tất cả deprecation warning. Bước 2: Bật CoW opt-in thông qua pd.options.mode.copy_on_write = True (có từ 2.0) và sửa các mẫu chained assignment. Bước 3: Cài đặt PyArrow và kiểm tra rằng suy luận dtype string không làm hỏng logic downstream (đặc biệt là kiểm tra dtype == object). Bước 4: Nâng cấp lên 3.0 và chạy toàn bộ test suite. Bước 5: Xóa các tham số copy= không còn tác dụng và cập nhật các lời gọi groupby(observed=).
Benchmark Hiệu Suất: Trước và Sau
Hiệu ứng kết hợp của CoW và PyArrow string mang lại cải thiện đo lường được trên các tải trọng thực tế:
# benchmark_example.py
import pandas as pd
import numpy as np
# Tạo DataFrame với 1 triệu hàng dữ liệu hỗn hợp
rng = np.random.default_rng(42)
df = pd.DataFrame({
"user_id": rng.integers(0, 100_000, size=1_000_000),
"event": rng.choice(["click", "view", "purchase", "scroll"], size=1_000_000),
"value": rng.exponential(50, size=1_000_000)
})
# Lọc string: ~6x nhanh hơn với backend PyArrow
clicks = df.loc[pd.col("event").str.contains("click")]
# Bộ nhớ: cột string sử dụng ~50% ít RAM hơn
print(df["event"].memory_usage(deep=True)) # ~8MB vs ~16MB với dtype object
# Subsetting: CoW tránh sao chép cho đến khi thay đổi
subset = df[["user_id", "value"]] # zero-copy (bộ nhớ chia sẻ)
subset["value"] = subset["value"].clip(upper=500) # bản sao chỉ được tạo ở đâyTrong các pipeline ETL sản xuất xử lý CSV chứa nhiều văn bản, chỉ riêng backend string PyArrow đã giảm bộ nhớ đỉnh 30-40% và cắt giảm tổng thời gian chạy 20-30% cho các phép biến đổi string-intensive.
Mẫu Di Chuyển Thực Tế: Sửa Lỗi Trong Thực Tế
Một codebase pandas 2.x điển hình cần các refactor cụ thể sau:
# migration_patterns.py
import pandas as pd
# Mẫu 1: Thay thế chained assignment
# Trước (pandas 2.x)
# df[df["status"] == "active"]["score"] = 100
# Sau (pandas 3.0)
df.loc[df["status"] == "active", "score"] = 100
# Mẫu 2: Xóa tham số copy=
# Trước
# subset = df[["a", "b"]].copy() # không cần thiết với CoW
# Sau
subset = df[["a", "b"]] # CoW xử lý cách ly tự động
# Mẫu 3: Cập nhật kiểm tra dtype cho string
# Trước
# if df["name"].dtype == object:
# Sau
if pd.api.types.is_string_dtype(df["name"]):
pass
# Mẫu 4: Tường minh observed= trong groupby
# Trước (dựa vào mặc định observed=False)
# df.groupby("category")["value"].sum()
# Sau (tường minh cho rõ ràng)
df.groupby("category", observed=True)["value"].sum()
# Mẫu 5: Keyword-only Index.sort_values()
# Trước
# idx.sort_values(True, "first")
# Sau
idx.sort_values(ascending=True, na_position="first")Để tìm hiểu thêm về các kỹ năng nền tảng về pandas và Python data analytics, các module câu hỏi phỏng vấn bao gồm các mẫu này một cách chi tiết. Module SQL window functions bổ sung kiến thức pandas cho các pipeline phân tích hỗn hợp.
Thẻ
Chia sẻ
Bài viết liên quan

Top 25 Câu Hỏi Phỏng Vấn Data Analytics Năm 2026
Hướng dẫn chi tiết 25 câu hỏi phỏng vấn Data Analyst thường gặp năm 2026, bao gồm SQL, Python, thống kê, visualization và behavioral questions kèm code examples.

Python cho Data Analytics: Matplotlib, Seaborn và Trực quan hóa Dữ liệu cho Phỏng vấn
Làm chủ trực quan hóa dữ liệu Python với Matplotlib và Seaborn. Hướng dẫn thực hành bao gồm biểu đồ, styling, subplot và các câu hỏi phỏng vấn thường gặp cho vị trí data analytics năm 2026.

SQL cho Data Analyst: Window Functions, CTEs và Truy vấn Nâng cao
Hướng dẫn chi tiết về SQL window functions, CTEs và các mẫu truy vấn nâng cao dành cho data analyst — từ RANK, LAG/LEAD đến gaps-and-islands.