Cách sửa lỗi 'ParserError: Error tokenizing data' trong Pandas

beginner🐍 Python2026-05-19| Python 3.x, thư viện Pandas (mọi phiên bản), Windows, macOS, hoặc Linux.

Error Message

pandas.errors.ParserError: Error tokenizing data. C error: Expected 3 fields in line 12, saw 5
#python#pandas#csv#khoa-hoc-du-lieu#khac-phuc-loi

Vấn đề

Nếu bạn sử dụng Python để phân tích dữ liệu, pd.read_csv() có lẽ là hàm bạn dùng nhiều nhất. Nhưng rồi chuyện đó cũng xảy ra: một đoạn mã hoạt động bình thường hôm qua bỗng dưng gặp lỗi ParserError khó hiểu. Nó thường trông như thế này:

pandas.errors.ParserError: Error tokenizing data. C error: Expected 3 fields in line 12, saw 5

Pandas rất khắt khe về cấu trúc. Nó thường xác định số lượng cột từ tiêu đề (header) hoặc vài dòng đầu tiên. Nếu dòng 12 chứa 5 cột nhưng tiêu đề chỉ định nghĩa 3, bộ phân tích (parser) được tối ưu hóa bằng C sẽ gặp lỗi. Đơn giản là nó không biết đặt hai mẩu dữ liệu thừa đó vào đâu.

Các nguyên nhân phổ biến

  • Dấu phẩy "lẻn" vào: Một dấu phẩy nằm bên trong một trường văn bản, ví dụ như địa chỉ ("123 Main St, Apt 4"), có thể đánh lừa Pandas khiến nó hiểu lầm là có thêm một cột nếu văn bản đó không được bao trong dấu ngoặc kép.
  • Các dòng bị hỏng: Các hệ thống xuất dữ liệu tự động đôi khi gặp lỗi, thêm các tab hoặc dấu phân cách thừa vào các dòng ngẫu nhiên ở giữa một tệp tin có 100.000 dòng.
  • Sai lệch dấu phân cách: Có thể bạn đang cố gắng đọc một tệp phân tách bằng dấu chấm phẩy (;) trong khi Pandas lại tìm kiếm dấu phẩy tiêu chuẩn (,).
  • Dữ liệu rác (Metadata): Một số tệp CSV bao gồm một vài dòng văn bản mô tả ở ngay đầu hoặc cuối tệp mà không tuân theo cấu trúc bảng.

Cách khắc phục

1. Bỏ qua các dòng gặp lỗi (Pandas 1.3.0+)

Đôi khi bạn chỉ cần phần dữ liệu thực sự hoạt động tốt. Nếu việc mất một vài dòng trong một tập dữ liệu khổng lồ không làm hỏng phân tích của bạn, hãy bảo Pandas bỏ qua các dòng "xấu". Đối với các phiên bản Pandas hiện đại, hãy sử dụng tham số on_bad_lines.

import pandas as pd

# Đoạn mã này bỏ qua các dòng bị hỏng và in ra cảnh báo cho mỗi dòng nó tìm thấy
try:
    df = pd.read_csv('data.csv', on_bad_lines='warn') 
except Exception as e:
    print(f"Không thể tải tệp: {e}")

# Hoặc, bỏ qua chúng một cách âm thầm để giữ cho bảng điều khiển sạch sẽ:
# df = pd.read_csv('data.csv', on_bad_lines='skip')

2. Giải pháp cho các phiên bản Pandas cũ hơn

Bạn đang bị kẹt trên một hệ thống cũ với phiên bản Pandas thấp hơn 1.3.0? Tên các tham số sẽ hơi khác một chút. Bạn sẽ cần sử dụng error_bad_lineswarn_bad_lines thay thế.

import pandas as pd

# Đặt error_bad_lines thành False để ngăn chặn lỗi dừng chương trình
df = pd.read_csv('data.csv', error_bad_lines=False, warn_bad_lines=True)

3. Định nghĩa rõ ràng dấu phân cách

Lỗi này thường xảy ra do Pandas xác định sai dấu phân cách. Nếu tệp của bạn sử dụng tab hoặc dấu chấm phẩy, hãy chỉ định rõ ràng. Bạn cũng có thể để Pandas tự đoán bằng cách sử dụng sep=None.

# Để engine tự động phát hiện xem đó là dấu phẩy, tab hay dấu chấm phẩy
df = pd.read_csv('data.csv', sep=None, engine='python')

# Hoặc chỉ định thủ công nếu bạn biết đó là tệp phân tách bằng dấu gạch đứng (pipe)
# df = pd.read_csv('data.csv', sep='|')

4. Chuyển sang Python Engine

Pandas mặc định sử dụng engine C vì nó cực kỳ nhanh. Tuy nhiên, engine Python linh hoạt hơn và xử lý các định dạng phức tạp tốt hơn. Nó chậm hơn đáng kể đối với các tệp hàng triệu dòng, nhưng nó có thể giải quyết được vấn đề phân tích của bạn.

df = pd.read_csv('data.csv', engine='python', on_bad_lines='skip')

5. Kiểm tra thủ công

Khi thông báo lỗi cho biết "Expected 3 fields in line 12, saw 5", nó đang cung cấp cho bạn một bản đồ chỉ dẫn. Hãy mở tệp trong một trình soạn thảo văn bản như VS Code hoặc Notepad++ và nhảy đến dòng 12. Bạn có thể sẽ thấy thứ gì đó như thế này:

# Vấn đề: Dấu phẩy thừa trong địa chỉ tạo ra cột thứ 4
ID,Name,Address
1,John Doe,123 Main St, New York

# Cách sửa: Bao trường đó trong dấu ngoặc kép
1,John Doe,"123 Main St, New York"

Xác minh dữ liệu của bạn

Sau khi áp dụng cách sửa lỗi, đừng vội giả định rằng mọi thứ đều hoàn hảo. Hãy kiểm tra tính toàn vẹn của dữ liệu đã nhập bằng ba lệnh sau:

  • Kiểm tra số lượng dòng: Chạy df.shape. Nếu bạn mong đợi 1.000 dòng nhưng chỉ thấy 800, bạn biết rằng 200 dòng đã bị bỏ qua.
  • Tìm các giá trị còn thiếu: Chạy df.isnull().sum(). Các dòng bị lệch thường dẫn đến một loạt các giá trị NaN.
  • Kiểm tra ngẫu nhiên: Sử dụng df.sample(10) để xem các dòng ngẫu nhiên và đảm bảo dữ liệu thực sự khớp với các tiêu đề cột.

Phòng ngừa chủ động

Để tránh điều này trong tương lai, hãy cố gắng chuyển hướng khỏi các tệp CSV thô nếu bạn có quyền kiểm soát quy trình (pipeline). Sử dụng các định dạng Parquet hoặc Feather giúp bảo toàn kiểu dữ liệu và cấu trúc một cách hoàn hảo, vì vậy bạn không bao giờ phải lo lắng về những dấu phẩy thừa nữa. Nếu bắt buộc phải sử dụng CSV, hãy đảm bảo tập lệnh xuất dữ liệu của bạn sử dụng tính năng bao ngoặc (quoting) thích hợp cho tất cả các trường văn bản.

Related Error Notes