Learning Objectives
- 用 csv 模組把量測結果寫成 CSV 檔,表頭寫清楚單位
- 用 csv.DictReader 讀回資料,用 statistics 算平均、標準差與標準誤
- 依量測的不確定度決定要報告幾位有效數字
- 了解積分時間與讀值雜訊的關係,用多筆讀值估計雜訊
量完之後:記下來、算出來、報告出去
前兩課的程式把結果印在畫面上,程式一結束就沒了。真正的量測要能留下紀錄、重新分析、交給別人:
- 記錄:寫成檔案。CSV(逗號分隔值)是最通用的格式,試算表、Python、MATLAB 都讀得懂。
- 分析:同一個量重複量幾次,用平均降低雜訊,用標準差說明讀值的分散程度。
- 報告:數字要帶單位,位數要合理。電錶印出
998.7212500000001,不代表你真的知道到小數點後 13 位。
這一課用 Python 標準函式庫的 csv 與 statistics 模組,不需要安裝其他套件。
資料量大的時候,常改用 pandas 與 NumPy,觀念相同。
逐步看:把量測結果寫成 CSV
受測電路是一顆 1 kΩ 電阻。程式邊量邊寫:每量一點就用 writer.writerow() 寫一列。
注意 open() 的三個參數:"w" 寫入、newline=""(交給 csv 模組處理換行)、encoding="utf-8"。
原始資料與處理後的資料分開存
寫檔的幾個習慣:
| 習慣 | 為什麼 |
|---|---|
表頭寫單位(current_A、freq_Hz) |
半年後打開檔案,不必猜 0.002 是安培還是毫安培 |
| 存原始讀值,不先四捨五入 | 四捨五入是報告時的事;資料存粗了就救不回來 |
| 一列一個量測點、一欄一個量 | 試算表與 pandas 都直接讀得進去 |
| 原始資料與分析結果分開 | 分析方法改了,可以從原始資料重算 |
| 檔名或另一個檔記下日期、儀器、設定 | 之後才知道這份資料是在什麼條件下量的 |
讀回來的時候,csv.DictReader 把每一列變成字典,用欄位名稱取值,比記「第幾欄」可靠。
讀到的一律是字串,計算前要用 float() 轉換。
逐步看:讀回 CSV、算統計量
readings.csv 是同一顆電阻重複量 8 次的結果。看 values 一筆一筆加進來,最後算出平均、標準差與標準誤。
有效位數:報告到哪一位
剛才的平均是 998.72125 Ω,標準誤約 0.017 Ω。報告成 998.72125 Ω 太多位,因為小數點後第三位已經不確定了;
報告成 999 Ω 又丟掉了量測的精密度。常見的做法:
- 不確定度取一到兩位有效數字:0.0166 → 0.017。
- 數值取到和不確定度同一位:998.72125 → 998.721。
- 寫成
998.721 ± 0.017 Ω,並說明 ± 代表什麼(標準差、標準誤,或其他信賴區間)。
Python 的 f-string 控制位數:
| 寫法 | 0.0193746 印出 | 說明 |
|---|---|---|
f"{i:.3f}" |
0.019 |
小數點後 3 位:只剩 2 位有效數字 |
f"{i:.3e}" |
1.937e-02 |
科學記號,小數點後 3 位:4 位有效數字 |
f"{i*1000:.2f} mA" |
19.37 mA |
先換成適合的單位再取位數,最好讀 |
round(x, 3) 回傳的是數字,存檔或繼續計算時用;f-string 回傳的是字串,報告時用。
另外,儀器規格書上的準確度(例如讀值的某個百分比加幾個位數)也是不確定度的一部分,正式報告要一起考慮,本課先只看重複量測的分散。
逐步看:依不確定度決定位數
report() 先算出不確定度的最高位在 10 的幾次方,再決定小數點後要留幾位。看 exp 與 nd 兩個變數。
小測驗:CSV 與統計
下面的程式會印出什麼?
import csv
import io
text = "n,volt_V\n1,1.5\n2,2.5\n"
rows = list(csv.DictReader(io.StringIO(text)))
print(rows[1]["volt_V"] + rows[0]["volt_V"])
下面的程式會印出什麼?
import statistics
v = [2.0, 4.0, 6.0]
print(statistics.mean(v), statistics.stdev(v))
同一顆電阻量 100 次,標準差 0.05 Ω。和量 4 次比起來,「平均值」的標準誤大約怎樣?
小測驗:有效位數
下面的程式會印出什麼?
v = 2.0315
print(f"{v * 1000:.1f} mV", f"{v:.2e}")
平均 1.91245 V,標準誤 0.0127 V。哪一種報告最恰當?
動手寫:LED 順向電壓的統計
DATA 是 8 顆 LED 在同樣電流下量到的順向電壓(CSV 格式,欄位 sn、vf_V;實際工作時就是一個 vf.csv 檔,把 io.StringIO(DATA) 換成 open("vf.csv", encoding="utf-8") 即可)。
讀進來之後印出筆數、平均與標準差(小數點後 3 位),再把超出 1.88~1.95 V 的 LED 序號與電壓印出來。
重點整理
- 寫 CSV:
open(檔名, "w", newline="", encoding="utf-8")加csv.writer,表頭寫單位,存原始讀值。 - 讀 CSV:
csv.DictReader用欄位名稱取值,讀到的是字串,要float()。 statistics.mean平均、statistics.stdev樣本標準差;平均值的標準誤=標準差 ÷ √n。- 報告:不確定度取一到兩位有效數字,數值取到同一位,寫成「數值 ± 不確定度 單位」並說明 ± 的意思。
- 積分時間(NPLC)越長,讀值雜訊越小、量測越慢。
下一課把這幾課的程式整理成有結構的測試程式:儀器類別、設定檔、記錄,以及可以替換的儀器驅動。