Lập trình
xử lý dữ liệu

Học kì 1, năm học 2026–2027

Viện Trí tuệ nhân tạo, Trường ĐH Công nghệ, ĐHQGHN

Bài 8
Xử lý dữ liệu
thời gian

Đọc đúng ngày giờ, tính theo kỳ và so sánh giữa các kỳ.

Bài trước

  • Chuẩn hoá chuỗi và trích xuất bằng regex.
  • Đổi giá sang số bằng to_numeric(errors="coerce"); giữ cột gốc để phân biệt giá thiếu với lỗi chuyển đổi.
  • Tách danh sách tiện nghi trong ô rồi tính tỷ lệ theo chỗ ở.
  • Ngày giờ cũng thường được lưu dưới dạng chuỗi; bài này đổi chúng thành ngày giờ để tính toán.

Tổng quan

  1. Đọc và tính toán với ngày giờ
  2. Tổng hợp theo thời gian
  3. So sánh giữa các kỳ
  4. Làm việc với AI thì sao?

Ví dụ thật: ngày ghi nhận đánh giá tại Santiago, mốc chụp 29/06/2026.

1.
Đọc và tính toán
với ngày giờ

Xác định cách ghi ngày trước khi đổi kiểu và tính toán.

Đổi chuỗi thành ngày giờ

Cần tính số ngày từ 28/02 đến 03/03/2026. Trừ trực tiếp hai chuỗi này được không?

to_datetime đổi chuỗi thành ngày giờ; format mô tả cách ghi: %d ngày, %m tháng, %Y năm bốn chữ số.

Ngày và tháng có thể bị đảo

Cả hai cách đọc đều hợp lệ. Cần dựa vào quy ước của nguồn dữ liệu để chọn format.

Ngày không hợp lệ và ngày bị thiếu

errors="coerce" đổi ngày không đọc được thành NaT (giá trị thiếu của ngày giờ) thay vì báo lỗi. Hàng 1 là lỗi chuyển đổi, hàng 2 thiếu từ nguồn; giữ cột gốc để phân biệt.

Lấy tháng và thứ trong tuần

Giống .str ở Bài 7, .dt lấy thành phần ngày giờ của cả cột.

dayofweek: thứ Hai = 0, …, Chủ nhật = 6. Có thể lấy thêm year, quarter.

Tính khoảng cách giữa hai ngày

Mỗi giá trị ngày giờ là một Timestamp; trừ hai Timestamp tạo Timedelta (khoảng thời gian). .days lấy số ngày; với một Series dùng .dt.days.

Bài tập 1: Tính số đêm lưu trú

Mỗi hàng là một lượt đặt. Ngày được ghi theo DD/MM/YYYY (giả lập).


dat = pd.DataFrame({
    "vao": ["03/07/2026", "10/07/2026"],
    "ra": ["06/07/2026", "12/07/2026"],
})
vao = pd.to_datetime(dat["vao"])
ra = pd.to_datetime(dat["ra"])
so_dem = (ra - vao).dt.days
print(so_dem.tolist())

Sửa code để tính đúng số đêm của từng lượt đặt.

Đổi múi giờ

📖 Tự học

Nhật ký (log) của phần mềm hoặc API có thể ghi thời điểm theo UTC (giờ phối hợp quốc tế).

tz_convert đổi cách hiển thị sang múi giờ khác. Cùng một thời điểm có thể thuộc hai ngày khác nhau, tuỳ múi giờ.

2.
Tổng hợp
theo thời gian

Đếm theo ngày, tháng và làm mượt các dao động.

Dữ liệu đánh giá tại Santiago

rv_raw là bảng đọc từ file reviews.csv: mỗi hàng là một đánh giá; date là ngày ghi nhận, viết theo năm-tháng-ngày.

Kiểm tra ngày vượt mốc chụp

pd.Timestamp tạo mốc chụp 29/06/2026 để so với cột date.

File có 204 hàng ghi ngày sau mốc chụp. Ta sẽ loại chúng khỏi phạm vi phân tích này.

Chọn dữ liệu theo năm và tháng

Đặt ngày làm chỉ mục (DatetimeIndex); sort_index() sắp theo thời gian để cắt được theo khoảng ngày.

.loc["2026-03"] lấy mọi hàng trong tháng 3/2026. Chỉ mục có thể có nhiều hàng cùng một ngày.

Gộp đánh giá theo tháng

Ví dụ giả lập có ba đánh giá: hai trong tháng 1, một trong tháng 3.

resample("ME") gộp theo tháng, gắn nhãn cuối tháng; size() đếm hàng. Tháng 2 có 0 đánh giá.

Đếm số đánh giá từng tháng

Có thể đổi ME thành D (ngày), W-SUN (tuần kết thúc Chủ nhật), QE (quý).

Tháng cuối chưa trọn

Mốc chụp là 29/06 nên tháng 6 chưa trọn, chưa so được với tháng 5.

replace(day=1) lấy đầu tháng chứa mốc chụp. Chỉ giữ các tháng có nhãn cuối tháng trước ngày 01/06.

Bài tập 2: Trung bình mỗi ngày

Hệ thống đã thu đủ dữ liệu từ 01–07/06/2026. Bảng chỉ liệt kê ngày có đánh giá (giả lập).

NgàySố đánh giá
01/062
03/061
07/064

Tính trung bình số đánh giá mỗi ngày trong tuần này.

Tính trung bình theo cửa sổ trượt

Để bớt dao động, mỗi tháng lấy trung bình của tháng đó và hai tháng trước.

Cửa sổ chuyển từ T1–T3 sang T2–T4. 3 là số hàng; min_periods=3 yêu cầu đủ 3 giá trị không thiếu.

Trung bình của sáu tháng gần nhất

Số đánh giá mỗi tháng và trung bình của tháng hiện tại cùng 5 tháng trước tại Santiago, 2016 đến tháng 5/2026
Mỗi điểm trên đường xanh là trung bình của tháng đó và 5 tháng liền trước.

3.
So sánh
giữa các kỳ

So tháng này với tháng trước hoặc với cùng tháng năm trước.

Đặt giá trị kỳ trước cạnh kỳ này

shift(1) dịch giá trị xuống một hàng; chỉ mục giữ nguyên. T1 chưa có kỳ trước nên nhận NaN.

Thiếu một tháng thì shift bị lệch

Tháng 3 nhận giá trị tháng 1 vì tháng 2 không có hàng. Với chuỗi do resample tạo, mỗi tháng đã có một hàng.

Tính tỷ lệ thay đổi

Kỳ gốc là kỳ dùng làm mẫu số, ở đây là kỳ liền trước: tỷ lệ thay đổi = (kỳ này − kỳ gốc) / kỳ gốc.

pct_change() trả về tỷ lệ: T2 là (12 − 10) / 10 = 0,2; nhân 100 mới ra phần trăm: 20,0%.

So với tháng liền trước

ThángSố đánh giá
04/202621.656
05/202622.296

Kỳ gốc là tháng 4/2026.

So với cùng tháng năm trước

ThángSố đánh giá
05/202514.509
05/202622.296

shift(12) lấy giá trị 12 hàng trước. Với chuỗi tháng liên tiếp, đó là cùng tháng năm trước.

Chọn kỳ gốc để so sánh

Tháng 5/2026 có 22.296 đánh giá.

Kỳ gốcThay đổiÝ nghĩa
Tháng 4/2026+3,0%Biến động tháng gần nhất
Tháng 5/2025+53,7%Biến động qua một năm

Hai kết quả dùng hai kỳ gốc khác nhau. So cùng tháng giúp giảm ảnh hưởng của những khác biệt theo mùa.

Tổng hợp theo tháng qua nhiều năm

Gộp bốn năm trọn gần nhất: 2022–2025.

tron.index.month là tháng của từng hàng, lấy từ chỉ mục nên không cần .dt. Chia số đánh giá của mỗi tháng (gộp bốn năm) cho trung bình của 12 tháng: 100 là mức trung bình.

Phân bố đánh giá theo tháng

Biểu đồ cột chỉ số đánh giá theo tháng, tổng hợp 4 năm 2022–2025, 100 là mức trung bình; từ tháng 1 đến tháng 12: 81, 67, 90, 84, 81, 85, 119, 125, 104, 118, 133, 112
Số đánh giá tăng khoảng 1,6 lần mỗi năm nên các tháng cuối năm cao hơn một phần chỉ vì xu hướng. Chỉ số này chưa tách xu hướng và chưa điều chỉnh số ngày từng tháng.

Bài tập 3: Tìm tháng tăng mạnh

Số đánh giá từng tháng năm 2025 (giả lập, các tháng đã trọn):

Tháng123456
Số đánh giá9012090150120240

Viết code tìm các tháng có số đánh giá cao hơn ít nhất 50% so với trung bình của 3 tháng liền trước.

Chỉ xét tháng có đủ 3 tháng trước để so sánh.

Tổng kết

  • Đọc đúng định dạng trước khi tính với ngày giờ.
  • resample gộp theo lịch; rolling tính trên cửa sổ trượt.
  • shift dịch theo hàng; so theo tháng cần lịch đủ mọi tháng.
  • Chọn kỳ gốc và kiểm phạm vi thời gian trước khi so sánh.

Làm việc với AI thì sao?

🤖 Làm việc với AI
AI làm tốtViết lệnh đọc ngày khi đã biết định dạng, tổng hợp theo kỳ và tính cửa sổ trượt.
AI hay saiĐoán định dạng ngày, coi hàng trước là tháng trước, so một kỳ chưa trọn với kỳ trọn, dùng mã tần suất cũ như "M" mà pandas 3 báo lỗi.

Kiểm chứng thế nào?

  • Thử ngày dễ nhầm ở hàng đầu tiên và một ngày không tồn tại để kiểm cách đọc. Nếu thiếu format, pandas đoán theo giá trị đầu tiên.
  • Đối chiếu một tháng bằng lọc ngày trực tiếp với kết quả resample.
  • In kỳ gốc, kỳ hiện tại và mốc chụp; tính lại kết quả cuối từ số đếm gốc.

Đọc thêm