同じ実験を繰り返すと、測定値は少しずつ変わります。前回は3つのCSVをグラフに重ねました。今回は、その3回分を同じ測定点ごとの平均と標準偏差にまとめます。
ゴールは、Pythonで各時刻の平均値とばらつきを計算し、表として確認できるようになることです。グラフへのエラーバー追加は別の機会に扱います。
1. 今回使うCSVとColabの準備
Pythonで複数のCSVをまとめてグラフ化で配布した次の3ファイルをそのまま使います。説明用の架空の測定データですが、この記事の数値はすべて実際の配布CSVから計算しています。
・run_01.csv
・run_02.csv
・run_03.csv
列名は time_s(時間・秒)と voltage_v(電圧・V)です。3ファイルとも6行で、時刻は0、1、2、3、4、5秒の順に一致しています。今回は同じ行が同じ時刻を表し、欠損値がないデータを対象にします。
Google Colabでノートブックを開き、次のセルを実行します。
from pathlib import Path
Path("data").mkdir(exist_ok=True)
左側のフォルダアイコンを開き、data フォルダを右クリックして「アップロード」から3つのCSVを入れます。前回試した複製の run_04.csv などは今回は data の外へ移してください。最初は上記3件だけで結果を確かめます。
※Colabのセッションが終了すると、アップロードしたファイルは消えることがあります。元のCSVはパソコンにも残してください。
2. 平均と標準偏差とは
平均は測定値を足して個数で割った値です。例えば0秒の3回分は0.20、0.25、0.15 Vなので、平均は0.20 Vになります。
標準偏差は測定値のばらつきを表す値です。小さいほど平均付近に集まり、大きいほどばらつきが大きい、と捉えてください。今回の標準偏差の単位もVです。
3. 3つのCSVを読み込み、電圧を取り出す
ここから、コードセルを追加して上から順番に実行します。最初に前回と同じ方法でCSVを探します。
import pandas as pd
from pathlib import Path
files = sorted(Path("data").glob("*.csv"))
print(files)
run_01.csv、run_02.csv、run_03.csv の3件が表示されることを確認します。[] ならファイルが見つかっていません。フォルダ名とアップロード先を確認してください。
data_list = []
for file in files:
df = pd.read_csv(file)
data_list.append(
df["voltage_v"].rename(file.stem)
)
pd.read_csv(file) で1ファイルずつ読み、df["voltage_v"] で電圧の列だけを取り出します。rename(file.stem) で run_01 などの名前を付け、data_list に順番にためています。
4. pd.concat(…, axis=1)で横に並べる
values = pd.concat(data_list, axis=1)
values
axis=1 は、ここでは列を横に並べる指定です。run_01、run_02、run_03 が1つの表になります。
このコードは行番号をそろえて結合します。時刻を自動で照合しているわけではありません。別のCSVを使うときも、行数と time_s の値、順番をそろえてください。ずれているデータの整列はこの記事では扱いません。
5. 同じ測定点の平均と標準偏差を求める
計算結果の列を追加する前に、測定値の列名を控えておきます。
measurement_cols = values.columns
次に、横に並んだ3回分から平均を計算します。mean(axis=1) は行ごとの平均です。
values["mean"] = values[measurement_cols].mean(axis=1)
標準偏差も同じ測定値の列を対象にして求めます。
values["std"] = values[measurement_cols].std(axis=1)
measurement_cols を使うのは、後から追加した mean や std を測定値に混ぜないためです。values.std(axis=1) とだけ書くと、すでに追加した平均列まで計算に入ってしまいます。
pandasの .std() はデフォルトが ddof=1 の標本標準偏差です。計算時には個数Nに対してN−1で割ります。ddof=0 とは結果が異なるため、他のソフトと比べる際は設定をそろえてください。今回は既定の ddof=1 を使います。
6. time_sも一緒に表示する
first_df = pd.read_csv(files[0])
values.insert(
0,
"time_s",
first_df["time_s"]
)
values
3ファイルの時刻が一致しているので最初のCSVの time_s を表の先頭へ追加します。測定値だけを集計してから時刻を加えるため、秒の数値が平均や標準偏差に混ざりません。
7. 完成コードと実行結果
最初からまとめて実行する場合は、次のコードを新しいセルに貼り付けて実行してください。data にCSV3件を置いた状態で使います。
import pandas as pd
from pathlib import Path
files = sorted(Path("data").glob("*.csv"))
data_list = []
for file in files:
df = pd.read_csv(file)
data_list.append(
df["voltage_v"].rename(file.stem)
)
values = pd.concat(data_list, axis=1)
measurement_cols = values.columns
values["mean"] = values[measurement_cols].mean(axis=1)
values["std"] = values[measurement_cols].std(axis=1)
first_df = pd.read_csv(files[0])
values.insert(
0,
"time_s",
first_df["time_s"]
)
values
6つの時刻に対して、meanとstdの列が表示されたら成功です。配布CSV3件の計算結果は次のとおりです(電圧は小数第2位まで表示)。
| time_s | run_01 | run_02 | run_03 | mean | std |
|---|---|---|---|---|---|
| 0 | 0.20 | 0.25 | 0.15 | 0.20 | 0.05 |
| 1 | 0.85 | 0.90 | 0.80 | 0.85 | 0.05 |
| 2 | 1.40 | 1.45 | 1.35 | 1.40 | 0.05 |
| 3 | 1.85 | 1.90 | 1.80 | 1.85 | 0.05 |
| 4 | 2.15 | 2.20 | 2.10 | 2.15 | 0.05 |
| 5 | 2.35 | 2.40 | 2.30 | 2.35 | 0.05 |
このサンプルでは、各時刻で3回分の値が同じ幅だけ離れているため、標準偏差はすべて0.05 Vになります。実際の測定では、時刻によってばらつきが変わることもあります。
やり直すときは完成コードのセル全体を再実行してください。表を作り直すため、計算結果の列が重複しません。insert の部分だけを再実行するとすでに time_s があるというエラーになります。
8. CSVが増えた場合
同じ列名・行数・時刻のCSVを data に追加し、完成コード全体を再実行すれば、増えた測定も含めて計算できます。コードに測定回数の「3」を書いていないため、列を手作業で追加する必要はありません。
独立した測定を追加してください。同じファイルを複製すると、その測定を重ねて数えることになります。欠損や行のずれがあるCSVは、そのまま混ぜないでください。なお、測定が1件だけの場合、今回の設定では標準偏差は NaN(計算できない値)になります。
できたことと、次の一歩
複数CSVの電圧を横に並べ、同じ測定点の平均と標準偏差を計算できました。測定値の列だけを選ぶことで、時刻や計算結果を混ぜずに集計できます。
重ねたグラフを見たい場合は、前回の複数CSVをグラフ化する記事も閲覧してみてください。平均とばらつきをグラフに表したい場合は、平均・標準偏差をエラーバー付きグラフにする方法へ進めます。
参考:pandas公式:concat / mean / std
Google Colabで動作確認(2026年9月13日):Python 3.13.15/pandas 2.2.3。画面やライブラリの更新により、表示が多少異なる場合があります。


コメント