Thao tác làm sạch dữ liệu với Python từ tập dữ liệu nhật ký API

Dữ liệu sạch là nền tảng cho mọi phân tích và nghiên cứu. Trong thực tế, các nhà khoa học dữ liệu thường dành tới 80% thời gian để xử lý, làm sạch dữ liệu – chỉ còn lại khoảng 20% cho việc phân tích thực sự. Việc làm sạch dữ liệu bao gồm nhiều thao tác như loại bỏ giá trị trùng lặp, xử lý thiếu sót, chuẩn hóa định dạng cột, phát hiện giá trị bất thường và đảm bảo tính nhất quán trong cấu trúc.

Trong ví dụ này, ta sẽ xử lý một tập tin log.txt chứa thông tin gọi API theo từng phút, gồm khoảng 180.000 dòng dữ liệu. Các trường bao gồm: số lượng lần gọi, tổng thời gian phản hồi, thời gian thấp nhất, cao nhất, trung bình, khoảng cách giữa các lần ghi nhận và thời điểm ghi nhận.

1. Nhập dữ liệu

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# Đọc file log.txt thành DataFrame
data = pd.read_table('log.txt', header=None, names=[
    'id', 'api', 'count', 'res_time_sum', 'res_time_min',
    'res_time_max', 'res_time_avg', 'interval', 'created_at'
])

# Xem vài dòng đầu tiên
print(data.head())

2. Khám phá dữ liệu ban đầu

Sau khi nhập dữ liệu, cần kiểm tra các đặc điểm cơ bản:

  • .shape: Kích thước bảng (số hàng, số cột)
  • .info(): Kiểu dữ liệu, số lượng giá trị không bị thiếu
  • .describe(): Thống kê mô tả về các cột số học
  • .isnull().sum(): Đếm số lượng giá trị rỗng
  • .duplicated().sum(): Kiểm tra số lượng bản ghi trùng lặp
  • .value_counts(): Phân tích tần suất các giá trị trong một cột

3. Làm sạch dữ liệu theo từng bước

Loại bỏ cột không cần thiết

Những cột như id, api, hoặc interval có thể mang tính lặp lại hoặc không hữu ích cho phân tích. Ví dụ:

# Loại bỏ cột không cần thiết
data_cleaned = data.drop(columns=['id', 'api', 'interval'])

Chuyển đổi kiểu dữ liệu thời gian

Cột created_at hiện đang ở dạng chuỗi. Để tiện lợi trong thao tác theo thời gian, cần chuyển nó thành kiểu Datetime:

data_cleaned['created_at'] = pd.to_datetime(data_cleaned['created_at'])

Đặt cột thời gian làm index

Để dễ dàng truy vấn theo thời gian, đặt cột thời gian làm chỉ mục chính:

data_cleaned.set_index('created_at', inplace=True)

Phát hiện và xử lý giá trị bất thường

Quan sát thống kê mô tả, ta thấy một số giá trị cực đoan – ví dụ như res_time_max lên đến hơn 140.000 ms. Cần xác định xem đây là lỗi ghi nhận hay sự kiện thật sự:

print(data_cleaned['res_time_max'].describe())

Nếu giá trị này nằm ngoài phạm vi hợp lý (ví dụ > 5000ms), có thể đánh dấu hoặc loại bỏ những bản ghi đó.

Chuẩn hóa tên cột

Nếu tên cột chưa rõ ràng, dùng phương thức rename():

data_cleaned.rename(columns={
    'count': 'call_count',
    'res_time_sum': 'total_response_time',
    'res_time_avg': 'avg_response_time'
}, inplace=True)

Xử lý giá trị thiếu

Không phải lúc nào cũng có giá trị thiếu. Nếu có, có thể dùng phương pháp:

  • Điền bằng giá trị trung bình
  • Điền bằng giá trị trước/ sau
  • Loại bỏ bản ghi nếu ít ảnh hưởng
data_cleaned.fillna(method='ffill', inplace=True)  # Điền theo giá trị trước

4. Phân tích theo thời gian

Với index đã là thời gian, việc truy xuất dữ liệu theo ngày, giờ trở nên đơn giản:

# Lấy toàn bộ dữ liệu trong ngày 01/05/2018
daily_data = data_cleaned['2018-05-01']

# Tính tổng số lần gọi theo giờ
hourly_calls = daily_data.resample('H').sum()['call_count']

Các biểu đồ trực quan như đường thời gian, histogram phân bố thời gian phản hồi giúp phát hiện xu hướng hoặc bất thường nhanh chóng.

Thẻ: Pandas data cleaning time series Datetime data analysis

Đăng vào ngày 30 tháng 8 lúc 15:56