2026年11月11日 星期三

Python Pandas實戰:從智慧養殖感測資料學習資料清理、統計與視覺化

Python Pandas實戰:從智慧養殖感測資料學習資料清理、統計與視覺化

智慧養殖系統中的感測器能持續記錄水溫、酸鹼值(pH)及溶氧量(DO)。但感測器傳來的資料不一定完整:可能漏值、重複上傳,甚至出現不合理的讀數。這篇文章將從一份小型模擬資料開始,透過Python Pandas學習「資料讀取 → 資料清理 → 統計分析 → 視覺化 → 結果輸出」,為後續AIoT與大數據分析打好基礎。

學習對象:已具備Python變數、串列、字典與基本函式概念的學生。準備工具:Python、Pandas、Matplotlib。本文數值均為教學模擬,不是水井村真實量測紀錄,也不構成養殖操作門檻建議。

一、為什麼智慧養殖需要資料分析?

假設養殖池每隔一段時間上傳一筆資料:時間、池別、水溫、pH、溶氧。IoT負責蒐集與傳送,Pandas負責整理與分析,視覺化協助人員理解趨勢。只有在確認資料品質後,才適合進一步做異常警示或AI模型訓練。

教學流程:感測器 → Wi-Fi/MQTT/HTTP → CSV或資料庫 → Pandas → 圖表與報表 → Django Dashboard / AIoT。

二、安裝套件與建立模擬資料

在終端機執行:

python -m pip install pandas matplotlib

以下程式可以一次建立兩個養殖池、八筆原始紀錄,刻意放入一筆缺漏溶氧、一筆重複資料及一筆不合理水溫,供後續練習。

import pandas as pd

records = [
    {"time": "2026-11-01 08:00", "pond": "A", "temp": 27.5, "ph": 7.6, "do": 6.2},
    {"time": "2026-11-01 09:00", "pond": "A", "temp": 28.0, "ph": 7.5, "do": 5.8},
    {"time": "2026-11-01 10:00", "pond": "A", "temp": 28.4, "ph": 7.4, "do": None},
    {"time": "2026-11-01 11:00", "pond": "A", "temp": 99.0, "ph": 7.3, "do": 5.2},
    {"time": "2026-11-01 08:00", "pond": "B", "temp": 29.1, "ph": 7.8, "do": 4.9},
    {"time": "2026-11-01 09:00", "pond": "B", "temp": 28.7, "ph": 7.7, "do": 5.1},
    {"time": "2026-11-01 10:00", "pond": "B", "temp": 28.5, "ph": 7.6, "do": 5.4},
    {"time": "2026-11-01 09:00", "pond": "B", "temp": 28.7, "ph": 7.7, "do": 5.1},
]

df = pd.DataFrame(records)
df.to_csv("pond_raw.csv", index=False, encoding="utf-8-sig")
print(df)

欄位說明:time為時間、pond為池別、temp為水溫(°C)、ph為酸鹼值、do為溶氧(mg/L)。

三、讀取CSV與檢視資料品質

import pandas as pd

df = pd.read_csv("pond_raw.csv", parse_dates=["time"])
print(df.head())
print(df.info())
print("缺漏數量:")
print(df.isna().sum())
print("完全重複筆數:", df.duplicated().sum())

預期可發現:do缺漏1筆、完全重複1筆。info()可以幫助我們檢查欄位型態;isna()負責找出缺漏值;duplicated()用來偵測重複紀錄。

四、資料清理:先辨識,再決定如何處理

本例採用示範性規則:水溫超出0~45°C視為待查核值,改為缺漏;這只是為了示範資料清理,不是適用所有魚種的安全水溫範圍。真實專案應先確認感測器規格、養殖物種及現場管理標準。

# 移除完全相同的重複紀錄
clean = df.drop_duplicates().copy()

# 將教學範例中不合理的水溫改成缺漏
clean.loc[~clean["temp"].between(0, 45), "temp"] = float("nan")

# 按池別與時間排序
clean = clean.sort_values(["pond", "time"])

# 以同一池的有效資料中位數填補缺漏
for col in ["temp", "do"]:
    clean[col] = clean.groupby("pond")[col].transform(
        lambda s: s.fillna(s.median())
    )

print(clean)
print("清理後缺漏數量:")
print(clean.isna().sum())

清理後共有7筆資料;A池11:00的99°C改由A池其他有效水溫的中位數28.0°C填補,A池10:00缺漏的溶氧以A池有效溶氧中位數5.8 mg/L填補。這些是估計值,不應在正式監控系統中偽裝成真實量測值。

實務提醒:正式系統建議保留原始資料、品質旗標與補值紀錄;資料缺漏若連續發生,應優先檢查感測器、電源與網路,而非一律自動補值。

五、Pandas統計分析:每個池子的平均值是多少?

summary = clean.groupby("pond").agg(
    samples=("temp", "size"),
    avg_temp=("temp", "mean"),
    min_temp=("temp", "min"),
    max_temp=("temp", "max"),
    avg_ph=("ph", "mean"),
    avg_do=("do", "mean"),
).round(2)
print(summary)

預期統計結果:

池別筆數平均水溫°C最低°C最高°C平均pH平均DO mg/L
A427.9827.528.47.455.75
B328.7728.529.17.705.13

從這份模擬資料可觀察到B池平均水溫較高、平均溶氧較低,但只有短時間的少量資料,不能據此推論因果或直接作出養殖管理決策。

六、Matplotlib視覺化:把數字變成趨勢圖

以下將水溫與溶氧分別繪製成兩張折線圖。兩個指標使用不同單位,因此不混用同一個縱軸。

import matplotlib.pyplot as plt

for column, ylabel, filename in [
    ("temp", "Temperature (C)", "temperature.png"),
    ("do", "Dissolved Oxygen (mg/L)", "oxygen.png"),
]:
    plt.figure(figsize=(9, 4))
    for pond, group in clean.groupby("pond"):
        plt.plot(group["time"], group[column], marker="o", label=f"Pond {pond}")
    plt.title(f"Aquaculture - {ylabel}")
    plt.xlabel("Time")
    plt.ylabel(ylabel)
    plt.legend()
    plt.grid(alpha=0.3)
    plt.xticks(rotation=30)
    plt.tight_layout()
    plt.savefig(filename, dpi=150)
    plt.show()

執行後會產生temperature.png與oxygen.png。圖表可以用來比較A、B池在不同時間的變化,但由於樣本少,應將其視為教學示範。

七、匯出清理資料與分析報表

clean.to_csv("pond_clean.csv", index=False, encoding="utf-8-sig")
summary.to_csv("pond_summary.csv", encoding="utf-8-sig")
print("已輸出 pond_clean.csv 與 pond_summary.csv")

CSV可以供Excel檢視,也可以交由Django讀取,建立網頁表格與趨勢圖。若要處理大量、持續增加的感測資料,則可進一步規劃時序資料庫、排程分析及Apache Spark等工具。

八、IoT、Pandas、Spark與AIoT如何分工?

技術核心工作智慧養殖例子
IoT資料感測與傳輸ESP32回傳水溫與溶氧
MQTT / HTTP資料通訊傳送資料至伺服器
Pandas表格資料清理與分析去重、補值、統計
Matplotlib圖表視覺化比較各池水質趨勢
Spark分散式大規模資料處理多場域長期歷史資料分析
AIoT結合IoT與AI分析決策異常偵測與輔助預警

重要觀念:資料量小時,Pandas通常已經足夠;不是所有IoT專案都需要Spark。當資料規模、處理速度或跨設備分析需求超出單機處理能力時,才評估分散式架構。

九、學生實作挑戰

  1. 基礎題:新增C池三筆模擬資料,重新計算各池平均水溫。
  2. 進階題:新增一個quality_flag欄位,標示原始量測、缺漏補值與不合理數值。
  3. 挑戰題:將資料改為每小時一筆、連續七天,繪製每日平均溶氧趨勢。
  4. 整合題:將清理後的CSV放到Django網站,提供池別查詢與趨勢圖。

十、延伸閱讀:智慧生活科技專業社群既有文章

以下連結可協助讀者從Python資料分析延伸至物聯網通訊與AIoT:

結語:讓感測資料真正成為智慧決策的基礎

智慧養殖不只是把感測器接上網路。真正有價值的流程,是蒐集可靠資料、辨識資料品質、整理歷史紀錄、觀察趨勢,再逐步建立可信賴的預警與決策支援。Pandas正是從Python基礎跨入資料科學與AIoT的重要起點。

下一篇建議:《Apache Spark與PySpark入門:當智慧養殖感測資料變成大數據,Python該如何處理?》

沒有留言:

張貼留言