Chuyển đến nội dung chính

Tái lấy mẫu Pandas với resample() và asfreq()

Hướng dẫn này khám phá tái lấy mẫu chuỗi thời gian trong pandas, bao gồm cả upsampling và downsampling bằng các phương pháp như .asfreq() và .resample().
· 7 phút đọc

Khám phá cùng AI

Thời gian là một chiều cơ bản trong phân tích dữ liệu. Theo thời gian, các giá trị có thể dao động, tạo xu hướng hoặc giữ ổn định. Khi phân tích cách dữ liệu biến đổi theo thời gian, chúng ta đang làm việc với chuỗi thời gian.

Một nhiệm vụ thường gặp trong phân tích chuỗi thời gian là điều chỉnh tần suất của ngày giờ trong dữ liệu, kỹ thuật này được gọi là tái lấy mẫu. Trong hướng dẫn này, chúng ta sẽ tận dụng Pandas, một thư viện có bộ công cụ mạnh mẽ để thao tác chuỗi thời gian trực quan và hiệu quả.

Chúng ta sẽ bắt đầu với những khái niệm cơ bản và dần tiến tới các kỹ thuật tái lấy mẫu nâng cao hơn. Bài viết cung cấp ví dụ thực tế và chia sẻ các thực hành tốt nhất để việc phân tích chuỗi thời gian hiệu quả và tối ưu hiệu năng.

Nếu bạn muốn tìm hiểu thêm về chuỗi thời gian, hãy xem khóa học về thao tác dữ liệu chuỗi thời gian trong Python.

Tái lấy mẫu chuỗi thời gian là gì?

Tương tự như cách chúng ta có thể nhóm dữ liệu theo danh mục, tái lấy mẫu cho phép nhóm dữ liệu vào các khoảng thời gian khác nhau. Điều này hữu ích cho cả làm sạch dữ liệu lẫn phân tích chuỗi thời gian chuyên sâu. Ví dụ, ta có thể cần căn chỉnh hai chuỗi thời gian về cùng một tần suất trước khi so sánh.

Có hai kiểu tái lấy mẫu chính:

  • Upsampling: Tăng tần suất dữ liệu (ví dụ: từ hàng năm lên hàng tháng). Việc này tạo ra các mốc thời gian mới cần được điền hoặc nội suy.
  • Downsampling: Giảm tần suất (ví dụ: từ hàng tháng xuống hàng năm). Việc này liên quan đến việc gộp các điểm dữ liệu trong những khoảng thời gian lớn hơn.

Tái lấy mẫu bằng phương thức asfreq() của Pandas

Chúng ta có thể tái lấy mẫu với pandas bằng hai phương thức chính: .asfreq() và .resample().

Để bắt đầu, trước tiên chúng ta cần nhập thư viện pandas với bí danh quen thuộc pd. Chúng ta cũng nhập matplotlib để trực quan hóa kết quả.

import pandas as pd
import matplotlib.pyplot as plt

Hãy bắt đầu với phương thức .asfreq(). Phương thức này chuyển một chuỗi thời gian về tần suất chỉ định, trả về dữ liệu gốc được căn chỉnh với chỉ mục mới ở tần suất đó.

Chúng ta sẽ làm việc với bộ dữ liệu chứa nhiệt độ hằng ngày ở Madrid từ năm 1997 đến 2015. Hãy bắt đầu với một vài bước tiền xử lý trước khi đi vào tái lấy mẫu.

url = 'https://raw.githubusercontent.com/jcanalesluna/courses_materials/master/datasets/Madrid%20Daily%20Weather%201997-2015.csv'
df = pd.read_csv(url, usecols=['CET', 'Max TemperatureC', 'Mean TemperatureC', 'Min TemperatureC'])

# Change column names
df.columns = ['time', 'max_temp', 'mean_temp', 'min_temp']

# Convert string column to datetime
df['time'] = pd.to_datetime(df['time'])

# Set time column as index
df = df.set_index('time')

df
image11.png

Upsampling với asfreq()

Để minh họa upsampling, giả sử chúng ta muốn chuyển dữ liệu nhiệt độ theo ngày thành theo giờ. Ta có thể thực hiện bằng phương thức .asfreq() với tham số freq='H'.

df_hour = df.asfreq('H')
df_hour

image2.png

Bộ dữ liệu thu được lớn hơn đáng kể, vì các hàng mới đã được tạo ở tần suất theo giờ thay vì theo ngày. Mặc định, .asfreq() lấy mục đầu tiên trong chỉ mục gốc và điền các giờ còn lại bằng giá trị null.

Bộ dữ liệu kết quả lớn hơn đáng kể, vì các hàng mới đã được tạo với dữ liệu theo giờ thay vì theo ngày. Theo mặc định, .asfreq() lấy mục đầu tiên trong chỉ mục gốc và tạo giá trị null cho các giờ còn lại.

Pandas cung cấp ba chiến lược để điền các giá trị null này:

  • Điền tiến (ffill): Lan truyền quan sát hợp lệ gần nhất về phía trước.
  • Điền lùi (bfill): Dùng quan sát hợp lệ kế tiếp để lấp khoảng trống.
  • Giá trị điền: Cung cấp một giá trị cụ thể để thay cho dữ liệu thiếu.

Hai chiến lược đầu được triển khai bằng tham số method trong phương thức .asfreq(), trong khi giá trị điền được chỉ định bằng tham số fill_value.

df_mean_temp = df[['mean_temp']]
df_mean_temp_hour= df_mean_temp.asfreq('H')

df_mean_temp_hour['ffill'] = df_mean_temp.asfreq('H', method='ffill')
df_mean_temp_hour['bfill'] = df_mean_temp.asfreq('H', method='bfill')
df_mean_temp_hour['value'] = df_mean_temp.asfreq('H', fill_value=0)
df_mean_temp_hour

image1.png

Downsampling với asfreq()

Bây giờ hãy xem downsampling. Giả sử chúng ta muốn đổi tần suất hằng ngày thành hằng tháng. Ta có thể thực hiện bằng .asfreq() với tham số freq='M'.

Trong trường hợp này, chúng ta đang giảm tần suất dữ liệu, chuyển từ theo ngày xuống theo tháng. DataFrame kết quả chỉ có 228 hàng, so với 6.812 hàng ở DataFrame gốc.

df_month = df.asfreq(freq='M')
df_month

image5.png

Lưu ý rằng .asfreq() chỉ đơn giản chọn ngày cuối cùng của mỗi tháng và dùng giá trị của ngày đó để đại diện cho cả tháng. Không có phép gộp nào được thực hiện (ví dụ: tính nhiệt độ trung bình theo tháng). Để thực hiện các phép gộp như vậy, chúng ta sẽ dùng phương thức .resample() ở phần tiếp theo.

Tái lấy mẫu bằng phương thức resample() của Pandas

Mặc dù .asfreq() hữu ích để hiển thị dữ liệu chuỗi thời gian ở tần suất khác, phương thức .resample() là công cụ ưu tiên khi cần thực hiện các phép gộp đồng thời với tái lấy mẫu.

Phương thức .resample() hoạt động khá giống .groupby(): nó nhóm dữ liệu trong một khoảng thời gian xác định rồi áp dụng một hoặc nhiều hàm cho mỗi nhóm. Kết quả của các hàm này được gán cho một ngày mới trong khoảng đó.

Chúng ta dùng .resample() cho cả upsampling (điền hoặc nội suy dữ liệu thiếu) và downsampling (gộp dữ liệu).

Hãy quay lại ví dụ chuyển đổi theo giờ để xem upsampling hoạt động với .resample() như thế nào. Áp dụng .resample() trả về một đối tượng Resampler, sau đó ta có thể áp dụng phương thức khác để thu được một DataFrame.

print(df.resample('H'))
DatetimeIndexResampler [freq=<Hour>, axis=0, closed=left, label=left, convention=start, origin=start_day]

Về upsampling, phương thức .resample() có thể thực hiện các tác vụ tương tự như .asfreq().

df.mean_temp.resample('H').asfreq()

Screenshot 2024-06-04 at 14.10.03.png

Chúng ta cũng có thể áp dụng các chiến lược điền và nội suy tương tự như với .asfreq(). Ví dụ, để dùng điền tiến:

df.mean_temp.resample('H').ffill()

image6.png

Nhưng .resample() cũng cung cấp các phương thức bổ sung mà .asfreq() không có. Chẳng hạn, chúng ta có thể dùng phương thức .interpolate(), ước lượng giá trị tại các mốc thời gian mới bằng cách tìm các điểm trên đường thẳng nối giữa các điểm dữ liệu hiện có.

df.mean_temp.resample('H').interpolate()

image8.png

Phương thức .resample() thực sự phát huy khi downsampling, vì nó cho phép áp dụng nhiều phương pháp gộp để tóm tắt dữ liệu. Ví dụ, hãy tính nhiệt độ trung bình theo tháng và trung vị theo quý ở Madrid bằng .resample().

df.mean_temp.resample('M').mean()

image4.png

df.mean_temp.resample('Q').median()

image7.png

Kỹ thuật tái lấy mẫu nâng cao

Ngoài các thao tác cơ bản, các phương thức tái lấy mẫu của Pandas cũng xử lý được những tình huống nâng cao hơn. Hãy cùng khám phá một số trường hợp phổ biến.

Tần suất thời gian tùy chỉnh

Tái lấy mẫu cho phép tạo chuỗi thời gian mới với tần suất phù hợp nhu cầu cụ thể. Một số tần suất thường dùng gồm:

  • W: Hàng tuần (kết thúc vào Chủ Nhật)
  • M: Cuối tháng theo lịch
  • Q: Cuối quý theo lịch
  • H: Hàng giờ

Tuy nhiên, Pandas cung cấp nhiều lựa chọn khác tùy yêu cầu. Chúng ta có thể xác định tần suất theo ngày đầu hoặc cuối kỳ, dùng ngày làm việc thay vì ngày lịch, thậm chí tạo tần suất hoàn toàn tùy chỉnh.

df.mean_temp.resample('M').mean() # calendar month end
df.mean_temp.resample('MS').mean() # calendar month start
df.mean_temp.resample('BM').mean() # business calendar end
df.mean_temp.resample('BMS').mean() # business calendar start

Nhiều phép gộp khi downsampling

Tương tự phương thức groupby(), .resample() cho phép áp dụng nhiều phép gộp đồng thời. Chúng ta có thể dùng .agg() và truyền vào danh sách các hàm gộp như mean, median và độ lệch chuẩn.

df.mean_temp.resample('M').agg(['mean','median','std'])

image3.png

Tái lấy mẫu: Thực hành tốt và lỗi thường gặp

Pandas được tối ưu hóa cao để xử lý tập dữ liệu lớn, nhưng khi kích thước DataFrame tăng, việc xử lý và thao tác có thể trở nên tốn tài nguyên tính toán. Điều này đặc biệt đúng với upsampling. Hãy tưởng tượng tái lấy mẫu chuỗi theo giờ xuống theo giây – DataFrame kết quả có thể khổng lồ!

Nếu gặp vấn đề hiệu năng với tập dữ liệu lớn, bạn có thể áp dụng các chiến lược sau:

  • Chỉ đọc các cột bạn cần dùng.
  • Dùng kiểu dữ liệu hiệu quả, tiêu tốn ít bộ nhớ hơn.
  • Dùng kỹ thuật chia lô (chunking) khi đọc tệp.

May mắn thay, các phiên bản pandas 2.0 trở lên đã tích hợp các kỹ thuật nâng cao để xử lý hiệu quả hơn. Bạn có thể tìm hiểu thêm trong bài viết về Pandas 2.0.

Kết luận

Tái lấy mẫu là một kỹ thuật nền tảng trong phân tích chuỗi thời gian, cho phép điều chỉnh tần suất dữ liệu bằng cách gộp (downsampling) hoặc nội suy (upsampling) các giá trị. Chúng ta đã khám phá cách pandas cung cấp các công cụ mạnh như .asfreq() và .resample() để giúp quy trình này trực quan và hiệu quả.

Để đào sâu hiểu biết về tái lấy mẫu và thao tác chuỗi thời gian trong Python, hãy xem các tài nguyên sau:

Javier Canales Luna

Tác giả

Javier Canales Luna

Tôi là một chuyên viên phân tích dữ liệu tự do, hợp tác với các công ty và tổ chức trên toàn thế giới trong các dự án khoa học dữ liệu. Tôi cũng là giảng viên khoa học dữ liệu với hơn 2 năm kinh nghiệm. Tôi thường xuyên viết bài về khoa học dữ liệu bằng tiếng Anh và tiếng Tây Ban Nha; một số bài đã được đăng trên các trang uy tín như DataCamp, Towards Data Science và Analytics Vidhya. Là một nhà khoa học dữ liệu có nền tảng khoa học chính trị và luật, mục tiêu của tôi là làm việc tại giao điểm giữa chính sách công, pháp luật và công nghệ, tận dụng sức mạnh của ý tưởng để thúc đẩy các giải pháp và cách tiếp cận mới nhằm giúp chúng ta đối mặt với những thách thức cấp bách, đặc biệt là khủng hoảng khí hậu. Tôi xem mình là người tự học, không ngừng trau dồi và là một người ủng hộ vững chắc cho tính đa ngành. Không bao giờ là quá muộn để học điều mới.

Câu hỏi thường gặp về tái lấy mẫu Pandas

Sự khác nhau giữa rolling và resample trong pandas là gì?

Tái lấy mẫu thay đổi tần suất dữ liệu chuỗi thời gian của bạn, trong khi các phép toán rolling tính toán thống kê trên một cửa sổ trượt có kích thước cố định trong tần suất gốc.

resample('MS') trong Python là gì?

resample('MS') là một tham số cụ thể trong phương thức .resample(). Nó yêu cầu pandas tái lấy mẫu dữ liệu theo tần suất bắt đầu tháng. 'MS' là viết tắt của Month Start (đầu tháng).

Khi nào tôi nên dùng tái lấy mẫu?

Tái lấy mẫu hữu ích cho nhiều tác vụ, bao gồm:

  • Căn chỉnh nhiều chuỗi thời gian về cùng một tần suất để so sánh.
  • Gộp dữ liệu về tần suất thấp hơn để phân tích hoặc trực quan hóa (ví dụ: dữ liệu hằng ngày thành trung bình hằng tháng).
  • Điền các điểm dữ liệu thiếu trong chuỗi thời gian thông qua nội suy (upsampling).
Nhược điểm của tái lấy mẫu là gì?
  • Upsampling có thể gây sai lệch nếu phương pháp nội suy không được chọn cẩn thận.
  • Downsampling có thể dẫn đến mất mát thông tin do dữ liệu bị gộp lại.
  • Tái lấy mẫu trên các tập dữ liệu lớn có thể tốn kém tài nguyên tính toán.

Chủ đề

Liên quan