pandas 3.0 ra mắt: 3 thay đổi lớn có thể làm code của bạn gãy (và cách nâng cấp an toàn)
pandas 3.0 mang string dtype mặc định và Copy-on-Write. Bài viết tóm tắt breaking changes, code dễ gãy và checklist nâng cấp an toàn.

pandas 3.0 ra mắt: 3 thay đổi lớn có thể làm code của bạn “toang” (và cách nâng cấp an toàn)
TL;DR
- pandas 3.0 đã phát hành (3.0.0) với nhiều cải tiến hiệu năng, nhưng có breaking changes.
- Mặc định mới: cột text sẽ là dtype
str(thay vìobject) — tốt hơn cho hiệu năng & type-safety, đặc biệt khi có PyArrow. - Copy-on-Write (CoW) trở thành mặc định/duy nhất: kết quả từ indexing/method “luôn behave như copy” → chained assignment không còn hoạt động; SettingWithCopyWarning cũng bị loại bỏ.
- Datetime-like mặc định chuyển sang microseconds (hoặc theo input) để giảm lỗi out-of-bounds khi xử lý năm quá xa.
- Để nâng cấp ít đau: lên pandas 2.3 trước, dọn warning, rồi mới lên 3.0.
Trong thế giới data/ML, pandas là “đồ nghề mặc định” của rất nhiều team. Vì vậy một major release như pandas 3.0 không chỉ là thêm tính năng — nó thay đổi cách bạn viết code hằng ngày, đặc biệt là các đoạn xử lý DataFrame kiểu “quick & dirty”.
Bài này sẽ tóm tắt điểm mới quan trọng, các pattern dễ gãy, và checklist nâng cấp để bạn lên 3.0 an toàn.
1) String dtype mặc định: tạm biệt object, chào str
Trước đây, phần lớn cột chứa text trong pandas sẽ là NumPy object. Vấn đề của object là:
- Không “chỉ dành cho string” (bất kỳ Python object nào cũng nhét vào được)
- Tốn RAM/CPU hơn trong nhiều thao tác
- Dễ làm code kiểm tra dtype bị “ảo” (tưởng string nhưng thực ra là object chứa đủ thứ)
Từ pandas 3.0, khi pandas infer dữ liệu, string column mặc định sẽ là dtype str:
import pandas as pd
s = pd.Series(["a", "b", None])
print(s.dtype) # pandas 3.0: 'str'Điểm đáng chú ý:
- dtype
strchỉ chứa string hoặc missing (nhét số/obj khác vào có thể fail) - Missing value của dtype này luôn là
NaN(không còn giữ nguyênNonenhư object) - Nếu bạn cài PyArrow, dtype mới có thể được backed bởi Arrow để tăng hiệu năng (nhưng PyArrow không bắt buộc)
Code nào dễ gãy?
- Code check dtype kiểu “string = object”:
# trước đây hay làm vậy
if s.dtype == "object":
...Giờ nên dùng cách bền hơn:
import pandas as pd
if pd.api.types.is_string_dtype(s.dtype):
...- Code phụ thuộc việc
Noneđược giữ nguyên trong series object. Với dtypestr,Nonethường sẽ thànhNaN.
2) Copy-on-Write (CoW): rule rõ ràng, nhưng phá nhiều thói quen
Đây là thay đổi “đụng nhiều code nhất”. Trước đây, pandas có sự lẫn lộn giữa view và copy:
- Có lúc bạn subset xong sửa, nó sửa luôn DataFrame gốc
- Có lúc subset xong sửa, nó không ảnh hưởng gì
- Và bạn nhận một đống SettingWithCopyWarning
Với pandas 3.0, Copy-on-Write trở thành mặc định/duy nhất. Quy tắc mới rất rõ:
Bất kỳ object (Series/DataFrame) tạo ra từ indexing hoặc method trả về object mới đều behave như copy ở level API.
Nói đơn giản: sửa “bản con” sẽ không bao giờ âm thầm sửa “bản cha” nữa.
2.1 Chained assignment: từ “lúc được lúc không” → “không bao giờ được”
Ví dụ pattern cũ:
# pandas < 3.0: có thể chạy, có thể warning, có thể không đúng như bạn nghĩ
df["foo"][df["bar"] > 5] = 100Trong pandas 3.0, pattern này không còn hoạt động. Viết lại chuẩn:
# pandas 3.0: làm 1 bước với .loc
df.loc[df["bar"] > 5, "foo"] = 1002.2 “Sửa Series con để DataFrame cha đổi theo” không còn
Một thói quen rất phổ biến:
subset = df["foo"]
subset.iloc[0] = 100
# trước đây có thể làm df thay đổi theo (khó đoán)Giờ: df sẽ không đổi. Nếu mục tiêu là sửa df, hãy sửa df trực tiếp:
df.iloc[0, df.columns.get_loc("foo")] = 100
# hoặc
# df.loc[df.index[0], "foo"] = 1002.3 Numpy view read-only
Một thay đổi khác (đáng chú ý nếu bạn thao tác low-level): các mảng NumPy lấy ra từ pandas có thể read-only để tránh mutate ngầm.
Nếu bạn muốn sửa mảng mà không quan tâm pandas object nữa, hãy tạo copy:
arr = df["foo"].to_numpy().copy()
arr[0] = 9993) Datetime-like mặc định: giảm lỗi “out-of-bounds”
Pandas trước đây thường default datetime/timedelta ở nanoseconds. Vấn đề là nanoseconds khiến giới hạn năm bị bó hẹp hơn, dễ dính lỗi khi gặp dữ liệu năm quá xa (trước 1678 hoặc sau 2262).
Pandas 3.0 chuyển default “resolution” sang microseconds (hoặc theo resolution của input), giúp giảm lỗi khi đọc dữ liệu lịch sử/định danh thời gian kỳ lạ.
Nếu pipeline của bạn xử lý time-series “khó chịu” (log lâu năm, dữ liệu legacy), đây là điểm cộng lớn.
4) Bonus: pd.col() — cú pháp mới để viết assign gọn hơn
Một tính năng nhỏ nhưng hữu dụng khi bạn hay viết assign:
import pandas as pd
df = pd.DataFrame({'a': [1, 1, 2], 'b': [4, 5, 6]})
# trước đây
out1 = df.assign(c=lambda df: df['a'] + df['b'])
# pandas 3.0: gọn hơn
out2 = df.assign(c=pd.col('a') + pd.col('b'))Cú pháp này mới ở mức “initial support”, nhưng khá hứa hẹn vì giúp code đọc giống expression hơn.
5) Checklist nâng cấp lên pandas 3.0 (thực dụng)
Nâng lên pandas 2.3 trước
- Mục tiêu: để pandas warning cho bạn biết chỗ nào sẽ đổi behavior.
Bật chế độ cảnh báo CoW (nếu bạn đang ở pandas 2.2+):
import pandas as pd
pd.options.mode.copy_on_write = "warn"Search & replace các pattern nguy hiểm
df["col"][mask] = ...→df.loc[mask, "col"] = ...df["col"].replace(..., inplace=True)→df.replace({"col": {...}}, inplace=True)hoặc gán lạidf["col"] = ...
Kiểm tra code lib/framework nội bộ
- Đặc biệt các đoạn “check dtype == object” để nhận diện string.
- Chuyển sang
pd.api.types.is_string_dtypehoặc checkdtype == "str"(tuỳ nhu cầu tương thích).
Cân nhắc cài PyArrow để hưởng lợi từ dtype string mới & interoperability:
python -m pip install -U pandas pyarrowKết luận
pandas 3.0 là một bước “dọn nhà lớn”: dtype string mặc định và Copy-on-Write làm API trở nên dễ đoán hơn, ít side-effect hơn, và mở đường cho tối ưu hiệu năng. Đổi lại, nó sẽ “đập” vào những codebase từng dựa vào hành vi mơ hồ của view/copy.
Nếu bạn muốn nâng cấp ít đau: lên 2.3 trước, chạy warning mode, sửa các pattern chained assignment, và chuẩn hoá việc xử lý string dtype. Làm được vậy thì lên 3.0 sẽ khá mượt.
Nguồn tham khảo
- Blog release: https://pandas.pydata.org/community/blog/pandas-3.0.html
- What’s new 3.0.0: https://pandas.pydata.org/docs/whatsnew/v3.0.0.html
- Migration guide (string dtype): https://pandas.pydata.org/docs/user_guide/migration-3-strings.html
- Copy-on-Write guide: https://pandas.pydata.org/docs/user_guide/copy_on_write.html
- GitHub releases: https://github.com/pandas-dev/pandas/releases
- Arrow PyCapsule interface (liên quan interoperability): https://arrow.apache.org/docs/format/CDataInterface/PyCapsuleInterface.html

