Thông báo: Download 4 khóa học Python từ cơ bản đến nâng cao tại đây.
Phân tích dữ liệu Apple Health bằng Python
Bài viết này hướng dẫn cách sử dụng Python để phân tích dữ liệu từ ứng dụng Apple Health, bao gồm:
- Nạp dữ liệu bài tập từ file XML vào Pandas DataFrame.
- Trích xuất các thống kê như thời gian tập và lượng calo tiêu thụ.
- Phân tích, vẽ biểu đồ dữ liệu nhịp tim.
- Lọc bài tập theo loại hoặc khoảng thời gian.
- Tạo biểu đồ tròn để hiển thị phần trăm các loại bài tập.
Cách sử dụng Python để phân tích dữ liệu từ ứng dụng Apple Health
Lấy dữ liệu từ Apple Health
Trên iPhone, vào ứng dụng Health App:
Profile → Export Data → Gửi file đến máy tính.
File sẽ được xuất dưới dạng Export.zip
. Giải nén file này, sau đó đặt file Export.xml
vào thư mục con có tên data
trong dự án. Các file khác có thể bỏ qua.
Cài đặt các thư viện cần thiết
Dự án yêu cầu hai thư viện chính là Pandas và Matplotlib. Cài đặt bằng pip:
pip install pandas matplotlib
Nạp dữ liệu XML vào Python
Tạo file Python mới (hoặc sử dụng Jupyter Notebook) và import dữ liệu:
Bài viết này được đăng tại [free tuts .net]
import xml.etree.ElementTree as ET import pandas as pd import datetime as dt import matplotlib.pyplot as plt plt.style.use("fivethirtyeight") # Tạo đối tượng ElementTree và nạp dữ liệu XML tree = ET.parse('data/Export.xml') root = tree.getroot() # Lấy tất cả các bản ghi từ file record_list = [x.attrib for x in root.iter('Record')]
Tạo DataFrame từ Pandas
Chuyển đổi danh sách dữ liệu thành DataFrame và điều chỉnh kiểu dữ liệu:
record_data = pd.DataFrame(record_list) # Định dạng các cột ngày tháng for col in ['creationDate', 'startDate', 'endDate']: record_data[col] = pd.to_datetime(record_data[col]) # Chuyển cột 'value' thành số, giá trị lỗi sẽ thành NaN record_data['value'] = pd.to_numeric(record_data['value'], errors='coerce') # Điền giá trị NaN thành 1.0 để dễ dàng xử lý record_data['value'] = record_data['value'].fillna(1.0) # Rút gọn tên loại quan sát record_data['type'] = record_data['type'].str.replace('HKQuantityTypeIdentifier', '') record_data['type'] = record_data['type'].str.replace('HKCategoryTypeIdentifier', '') record_data.tail()
Trích xuất dữ liệu bài tập
Tạo một DataFrame riêng cho dữ liệu bài tập:
workout_list = [x.attrib for x in root.iter('Workout')] workout_data = pd.DataFrame(workout_list) # Rút gọn tên loại bài tập workout_data['workoutActivityType'] = workout_data['workoutActivityType'].str.replace('HKWorkoutActivityType', '') workout_data = workout_data.rename({"workoutActivityType": "Type"}, axis=1) # Chuyển đổi kiểu dữ liệu for col in ['creationDate', 'startDate', 'endDate']: workout_data[col] = pd.to_datetime(workout_data[col]) workout_data['duration'] = pd.to_numeric(workout_data['duration']) workout_data['totalEnergyBurned'] = pd.to_numeric(workout_data['totalEnergyBurned']) workout_data['totalDistance'] = pd.to_numeric(workout_data['totalDistance']) workout_data.tail()
Phân tích dữ liệu bài tập
Số lượng bài tập
num_workouts = workout_data.shape[0] print(f"Số lượng bài tập: {num_workouts}")
Lọc bài tập theo loại
def get_workouts(df, workout_type): return df[df["Type"] == workout_type] print(workout_data.Type.unique()) # Liệt kê các loại bài tập running_data = get_workouts(workout_data, "Running")
Lọc bài tập theo khoảng thời gian
def get_workouts_from_to(df, start, end): start = pd.to_datetime(start, utc=True) end = pd.to_datetime(end, utc=True) workouts = df[df["creationDate"] >= start] workouts = workouts[workouts["creationDate"] <= end] return workouts lower_time = dt.date(2021, 1, 1) upper_time = dt.date(2022, 1, 1) workouts = get_workouts_from_to(workout_data, lower_time, upper_time)
Phân tích nhịp tim
Trích xuất dữ liệu nhịp tim và tính toán thống kê:
heartrate_data = record_data[record_data["type"] == "HeartRate"] def get_heartrate_for_workout(heartrate, workout): def get_heartrate_for_date(hr, start, end): hr = hr[hr["startDate"] >= start] hr = hr[hr["endDate"] <= end] return hr return get_heartrate_for_date(heartrate, workout["startDate"].item(), workout["endDate"].item()) last_workout = workouts.iloc[[-1]] heartrate_workout = get_heartrate_for_workout(heartrate_data, last_workout) minh = heartrate_workout["value"].min() maxh = heartrate_workout["value"].max() meanh = heartrate_workout["value"].mean() print(f"Loại bài tập: {last_workout.Type.item()}, Nhịp tim thấp nhất: {minh}, Cao nhất: {maxh}, Trung bình: {meanh}")
Vẽ biểu đồ bài tập
Biểu đồ tròn hiển thị phần trăm các loại bài tập:
def plot_workouts(workouts): labels = [] slices = [] for wo_type in workouts.Type.unique(): labels.append(wo_type) wo_of_type = workouts[workouts["Type"] == wo_type] slices.append(wo_of_type.shape[0]) def make_autopct(values): def my_autopct(pct): total = sum(values) val = int(round(pct*total/100.0)) return f'{pct:.2f}% ({val})' return my_autopct plt.figure(figsize=(10, 10)) plt.pie(slices, labels=labels, shadow=True, startangle=90, autopct=make_autopct(slices), wedgeprops={'edgecolor': 'black'}) plt.title("Phân bố bài tập năm 2021") plt.tight_layout() plt.show() plot_workouts(workouts)
Thống kê tổng quan
def get_stats(workouts): total_kcal = workouts["totalEnergyBurned"].sum() total_dist = workouts["totalDistance"].sum() total_time = workouts["duration"].sum() print(f"Số bài tập: {workouts.shape[0]}") print(f"Tổng thời gian: {total_time:.2f} phút") print(f"Lượng calo tiêu thụ: {total_kcal:.2f} kcal") print(f"Tổng quãng đường chạy: {total_dist:.2f} km") get_stats(workouts)