一、前言
在前幾天的學習中,我已經完成健康紀錄的新增、查詢、修改與刪除,並且初步建立了個人健康儀表板,讓使用者可以查看每日的喝水量、睡眠時間與運動分鐘數。
然而,只有單筆紀錄還不足以觀察長期的生活習慣。例如,某一天喝了 2000 毫升的水,不代表每天都有達到相同的喝水量;某一天睡了 8 小時,也不代表平時的睡眠時間都很充足。
因此,今天的目標是學習使用 Python 的 Pandas 套件計算平均喝水量與平均睡眠時間,並將統計結果整合至 Streamlit 健康儀表板,讓使用者更容易了解自己的生活習慣。
二、學習目標
認識平均值的計算方式。
使用 Pandas 的 mean() 計算平均喝水量與平均睡眠時間。
學習處理空白、無效或非數字的資料。
將統計結果顯示在 Streamlit 網頁上。
了解平均值的限制,避免只根據單一統計數字判斷健康狀況。
三、認識平均值與 Pandas
平均值是一種常見的統計指標,可以協助我們了解一組資料的整體情況。
計算方式如下:
平均值 = 所有有效數值的總和 ÷ 有效數值的筆數
假設最近三筆睡眠紀錄分別為 6、7、8 小時:
[
\frac{6+7+8}{3}=7
]
因此,這三筆紀錄的平均睡眠時間為 7 小時。
在 Pandas 中,可以使用 mean() 計算平均值:
import pandas as pd
sleep_data = pd.Series([6, 7, 8])
average_sleep = sleep_data.mean()
print(average_sleep)
執行結果:
7.0
同樣的方式也能用來計算喝水量。
water_data = pd.Series([1500, 2000, 1800])
average_water = water_data.mean()
print(average_water)
執行結果:
1766.6666666666667
這代表三筆紀錄的平均喝水量約為 1767 毫升。
四、讀取健康紀錄並處理資料
目前系統將健康資料儲存在 health_records.csv,其中包含以下欄位:
在進行統計前,需要先讀取資料,並確保喝水量與睡眠時間是可以計算的數字。
例如,資料可能因為輸入錯誤而出現空白或文字。如果直接將這些內容當成數字運算,就可能造成錯誤。因此,我們可以使用 pd.to_numeric() 搭配 errors="coerce",將無法轉換的內容設為缺失值 NaN。
import pandas as pd
from pathlib import Path
FILE_PATH = Path("health_records.csv")
if FILE_PATH.exists():
records = pd.read_csv(FILE_PATH)
records["water_ml"] = pd.to_numeric(
records["water_ml"],
errors="coerce"
)
records["sleep_hours"] = pd.to_numeric(
records["sleep_hours"],
errors="coerce"
)
print(records)
else:
print("目前尚無健康紀錄。")
這個步驟可以讓後續的統計更加穩定。不過,將文字轉換成缺失值並不代表資料一定合理;例如負數喝水量或負數睡眠時間,仍然需要額外的資料驗證。
五、實作:在健康儀表板顯示平均值
接下來,將平均喝水量與平均睡眠時間整合到 Streamlit 網頁。
請在專案資料夾中開啟 app.py,將原本的程式碼備份後,替換成以下完整版本。
from pathlib import Path
import pandas as pd
import streamlit as st
FILE_PATH = Path("health_records.csv")
st.set_page_config(
page_title="個人健康習慣追蹤系統",
page_icon="🌱",
layout="wide"
)
st.title("🌱 個人健康習慣追蹤系統")
st.subheader("睡眠與喝水量統計")
if not FILE_PATH.exists():
st.info("目前尚無健康紀錄,請先新增每日健康資料。")
st.stop()
try:
records = pd.read_csv(FILE_PATH)
except (OSError, pd.errors.ParserError, UnicodeDecodeError):
st.error("讀取健康紀錄失敗,請檢查 CSV 檔案。")
st.stop()
if records.empty:
st.info("目前沒有可供統計的健康紀錄。")
st.stop()
required_columns = ["water_ml", "sleep_hours"]
missing_columns = [
column
for column in required_columns
if column not in records.columns
]
if missing_columns:
st.error(
"健康紀錄缺少必要欄位:" + ", ".join(missing_columns)
)
st.stop()
records["water_ml"] = pd.to_numeric(
records["water_ml"],
errors="coerce"
)
records["sleep_hours"] = pd.to_numeric(
records["sleep_hours"],
errors="coerce"
)
valid_water = records.loc[
records["water_ml"].ge(0),
"water_ml"
].dropna()
valid_sleep = records.loc[
records["sleep_hours"].ge(0),
"sleep_hours"
].dropna()
average_water = (
valid_water.mean()
if not valid_water.empty
else None
)
average_sleep = (
valid_sleep.mean()
if not valid_sleep.empty
else None
)
col1, col2 = st.columns(2)
with col1:
st.metric(
"平均喝水量",
f"{average_water:,.0f} 毫升"
if average_water is not None
else "尚無有效資料"
)
st.caption(f"有效紀錄筆數:{len(valid_water)}")
with col2:
st.metric(
"平均睡眠時間",
f"{average_sleep:.1f} 小時"
if average_sleep is not None
else "尚無有效資料"
)
st.caption(f"有效紀錄筆數:{len(valid_sleep)}")
st.divider()
st.subheader("健康紀錄明細")
st.dataframe(records, use_container_width=True)
st.caption(
"統計結果以目前檔案中的有效紀錄計算;"
"同一天若有多筆紀錄,每筆都會納入平均值。"
)
程式碼重點說明
系統會從 CSV 檔案取得過去保存的健康紀錄,不需要每次開啟網站時重新輸入。
records["water_ml"] = pd.to_numeric(
records["water_ml"],
errors="coerce"
)
這段程式會將喝水量轉換成數字,無法轉換的內容則設為缺失值,避免文字影響計算。
average_water = valid_water.mean()
average_sleep = valid_sleep.mean()
mean() 會計算有效數值的平均值。程式另外檢查資料是否為空,避免沒有有效紀錄時顯示錯誤。
st.metric() 可以用來顯示重要數字,例如平均喝水量、平均睡眠時間等。透過儀表板,使用者不必自行計算,就能快速掌握目前紀錄的整體情況。
六、實際執行與測試
完成程式碼後,開啟終端機,進入專案資料夾,執行:
python -m streamlit run app.py
接著,依照以下測試案例確認功能是否正常。
測試時,建議先建立幾筆測試資料,確認平均值與手動計算的結果一致。若需要修改 CSV 進行測試,請先備份原始檔案,以免影響已保存的健康紀錄。
另外,本日程式只排除負數與無效資料,尚未設定喝水量或睡眠時間的合理上限;這些條件可以在後續的資料驗證與系統測試階段進一步完善。
七、今日成果與學習心得
今天完成了健康習慣追蹤系統的基礎統計功能,學習如何透過 Pandas 計算平均喝水量與平均睡眠時間,並利用 Streamlit 將結果呈現在網頁儀表板上。
透過這次實作,我了解到資料保存只是健康追蹤系統的第一步。當系統累積了一定數量的紀錄後,還需要透過統計方法,將原始數字轉換成更容易理解的資訊。
同時,我也認識到資料品質對統計結果的重要性。若紀錄中包含空白、文字或不合理的數值,就可能影響分析結果。因此,資料驗證與統計功能需要互相配合。
需要注意的是,平均值只能反映目前有效紀錄的整體情況,不能直接代表每一天的表現,也不能單獨用來判斷個人的健康狀態。若要進一步了解生活習慣的變化,還需要搭配日期、每週統計與圖表進行分析。
八、下一步學習方向
第二十天將進入「每週運動分析——統計運動時間與次數」。
下一階段將學習如何利用日期篩選健康紀錄,計算每週的運動總分鐘數與運動次數,並比較不同週的活動情況,讓個人健康習慣追蹤系統從單純的資料記錄,逐步發展成具備時間區間分析能力的工具。