python-048Đọc toàn bộ đề miễn phí

Thiết kế Pipeline Kiểm tra Tính hợp lệ & Làm sạch Dữ liệu Khai báo

Trong các hệ thống Data Lakehouse hiện đại, dữ liệu thô (Raw Data) từ nhiều nguồn thứ ba gửi về thường chứa lỗi: thiếu trường, sai định dạng email/SĐT, số âm vô lý, hoặc trùng lặp…

PythonNâng cao35 phút

Tiến độ của tôi ở bài này

Điểm được lưu vào tài khoản sau khi chấm bài.

Đang tải điểm của bạn…

Kiến thức và chủ đề

pandasdata qualityschema validationdata cleaningpipeline

Kiến thức tiên quyết: dataframe iteration, regex validation, type casting, duplicate detection.

Nội dung đề bài

Mục tiêu kiến thức

  • Xây dựng động cơ kiểm soát chất lượng dữ liệu (Data Quality & Schema Validation Engine) theo hướng khai báo (Declarative).
  • Thực thi các quy tắc kiểm thử nghiêm ngặt: Kiểm tra sự tồn tại của cột, giá trị rỗng (nullable), kiểm tra kiểu (int, float, string), giới hạn miền giá trị (min, max), và biểu thức chính quy (regex).
  • Phát hiện và loại bỏ các bản ghi trùng lặp khóa chính (dedup_keys), chỉ giữ lại bản ghi hợp lệ xuất hiện đầu tiên.
  • Phân tách luồng dữ liệu thành hai bảng: Bảng dữ liệu sạch đã ép kiểu chuẩn (valid_df) và Bảng dữ liệu lỗi kèm danh sách lý do vi phạm (invalid_df).

Mô tả bài toán

Trong các hệ thống Data Lakehouse hiện đại, dữ liệu thô (Raw Data) từ nhiều nguồn thứ ba gửi về thường chứa lỗi: thiếu trường, sai định dạng email/SĐT, số âm vô lý, hoặc trùng lặp mã đơn hàng. Để đảm bảo dữ liệu đưa vào kho không bị ô nhiễm, cần có một pipeline kiểm duyệt tự động.

Hãy viết hàm: validate_and_clean_data(df: pd.DataFrame, schema: dict) -> tuple[pd.DataFrame, pd.DataFrame]

Cấu trúc đối tượng schema:

schema = {
    "columns": {
        "col_name": {
            "type": "int" | "float" | "string",
            "nullable": bool,
            "min": float | int,    # Tùy chọn (chỉ áp dụng cho int/float)
            "max": float | int,    # Tùy chọn (chỉ áp dụng cho int/float)
            "regex": str           # Tùy chọn (chỉ áp dụng cho string)
        }
    },
    "dedup_keys": list[str]        # Tùy chọn danh sách cột khóa duy nhất
}

Quy tắc kiểm tra từng dòng theo thứ tự ưu tiên:

  • Kiểm tra cột bắt buộc:
  • Nếu một cột khai báo trong schema["columns"] hoàn toàn không tồn tại trong df.columns, TOÀN BỘ các dòng của df đều bị coi là lỗi với mã lý do: f"MISSING_COLUMN_{col}".
  • Kiểm tra Giá trị Rỗng (nullable):
  • Nếu ô dữ liệu là rỗng (pd.isna(val)) mà cột đó có nullable=False: thêm lý do f"NULL_NOT_ALLOWED_{col}".
  • Kiểm tra Kiểu & Giới hạn (với ô không rỗng):
  • Thử ép kiểu:
  • Với type == 'int': Thử chuyển sang số nguyên (chuỗi biểu diễn số nguyên hợp lệ hoặc số thực có phần thập phân bằng 0). Nếu thất bại, ghi nhận f"INVALID_TYPE_{col}".
  • Với type == 'float': Thử chuyển sang số thực float(val). Nếu thất bại, ghi nhận f"INVALID_TYPE_{col}".
  • Với type == 'string': Giá trị phải là chuỗi ký tự (hoặc ép sang chuỗi).
  • Kiểm tra miền giá trị (nếu ép kiểu thành công cho int/float):
  • Nếu có khai báo min và val < min: ghi nhận f"OUT_OF_RANGE_MIN_{col}".
  • Nếu có khai báo max và val > max: ghi nhận f"OUT_OF_RANGE_MAX_{col}".
  • Kiểm tra định dạng Regex (cho string):
  • Nếu có khai báo regex và re.match(regex, str(val)) không khớp: ghi nhận f"PATTERN_MISMATCH_{col}".
  • Kiểm tra Trùng lặp Khóa (dedup_keys):
  • Chỉ áp dụng kiểm tra trùng lặp cho các dòng không vi phạm bất kỳ quy tắc nào ở trên.
  • Nếu giá trị tổ hợp các cột trong dedup_keys đã từng xuất hiện ở một dòng hợp lệ trước đó, dòng hiện tại bị đánh dấu lỗi với lý do "DUPLICATE_KEY".
  • Đầu ra:
  • valid_df: DataFrame gồm các dòng hợp lệ, các cột được ép kiểu chuẩn mực (int64, float64, object), reset index drop=True.
  • invalid_df: DataFrame gồm các dòng vi phạm, giữ nguyên giá trị ban đầu, thêm cột mới error_reasons (dạng list[str]), reset index drop=True.
  • Trả về (valid_df, invalid_df).

Input

  • Các tham số truyền vào hàm/lớp validate_and_clean_data hoặc dữ liệu đầu vào theo định dạng mô tả.

Output

  • Kết quả trả về của hàm/lớp validate_and_clean_data hoặc dữ liệu in ra màn hình theo đúng đặc tả.

Ràng buộc

  • Số dòng dữ liệu: 0 ≤ N ≤ 104.
  • Schema luôn có khóa "columns" hợp lệ.

Ví dụ 1

Input

validate_and_clean_data(data=[{'user_id': 1, 'email': 'alice@domain.com', 'age': 25, 'score': 95.5}, {'user_id': 2, 'email': 'invalid_email_format', 'age': 30, 'score': 80.0}, {'user_id': 3, 'email': 'charlie@domain.com', 'age': 150, 'score': 75.0}], schema={'columns': {'user_id': {'type': 'int', 'nullable': False}, 'email': {'type': 'string', 'regex': '^[\\w\\.-]+@[\\w\\.-]+\\.\\w+$', 'nullable': False}, 'age': {'type': 'int', 'min': 18, 'max': 120, 'nullable': True}, 'score': {'type': 'float', 'min': 0.0, 'max': 100.0, 'nullable': True}}, 'dedup_keys': ['user_id']})

Output

1

Giải thích

Hàm được gọi với các tham số mẫu trên và trả về kết quả chính xác theo yêu cầu.

Ví dụ 2

Input

validate_and_clean_data(data=[{'uid': 101, 'name': 'first_entry'}, {'uid': 101, 'name': 'duplicate_entry'}], schema={'columns': {'uid': {'type': 'int', 'nullable': False}, 'name': {'type': 'string', 'nullable': False}}, 'dedup_keys': ['uid']})

Output

1

Giải thích

Hàm được gọi với bộ tham số thứ hai và trả về kết quả tương ứng theo thiết kế.

3 cấp độ gợi ýMở dần khi bạn thật sự cần hỗ trợ.
Phân tích lời giảiGiải thích hướng tư duy và thuật toán.
Code tham khảoDùng để đối chiếu sau khi tự làm.

Gợi ý và lời giải chỉ mở sau khi bạn bấm Nộp bài. Giáo viên và quản trị viên mở được ngay.