Python環境を起動中... 初回のみ数秒かかります
Lesson 8 / 12

軸(axis)と集計

このレッスンで学ぶこと

  • axis 引数の意味を理解し、行ごと・列ごとに集計できる
  • axis=0axis=1 を直感的に使い分けられる
  • keepdims=True で集計後も元の次元を保てる
  • argmax / argmin で最大・最小の位置を取得できる

1. なぜ axis を学ぶのか

前のレッスンでは arr.mean()配列全体の平均を計算しました。 しかし2次元以上の配列では「どの方向に集計するか」を選ぶ必要があります。

例えば、患者4人 × 検査3項目のデータがあるとき、知りたい平均は2種類あります:

これらを切り替えるための引数が axis です。 このレッスンで「axisの直感」を身につければ、2D・3Dデータの集計で迷うことはなくなります。

2. axis=0 vs axis=1 の直感

まずは結論を先に示します。

指定意味結果の shape例:(4, 3) の場合
なし全体を1つの値に集計スカラー全12要素の平均1つ
axis=0「行を潰す」= 各列の集計(列数,)(3,) ← 項目ごとの平均
axis=1「列を潰す」= 各行の集計(行数,)(4,) ← 患者ごとの平均

💡 覚え方の鉄則: 「axis で指定した軸が消える(潰れる)」と覚えるのが一番分かりやすいです。 (4, 3)axis=0 を指定すると、軸0(行)が潰れて (3,) が残ります。 axis=1 なら軸1(列)が潰れて (4,) が残ります。

sample_1.py
Ctrl+Enter
出力

🩺 医療AI文脈: 「患者×特徴量」の2次元データは医療AIで最も典型的な形です。 axis=0(項目ごと)の集計は 特徴量の前処理(平均0・標準偏差1の正規化)で必須、 axis=1(患者ごと)の集計は 個別患者のスコア計算で頻出します。

3. keepdims=True — 次元を保つ

集計すると基本的に 次元数が1つ減ります(軸が潰れる)。 ただし、keepdims=True を指定すると 潰れた軸をサイズ1のまま残してくれます。 これは次のレッスンで学ぶ「ブロードキャスト」と組み合わせて、正規化などで威力を発揮します。

sample_2.py
Ctrl+Enter
出力

💡 なぜ keepdims が必要なのか: (4, 3) から正規化したい場合、各列の平均を引きたいですが、 (3,) ではなく (1, 3) の方が 元のデータと自然に演算できます。 この「形を保ったまま集計する」テクニックは、次のレッスン「ブロードキャスト」で本領発揮します。

4. argmax / argmin — 最大・最小の「位置」

max / min値そのものを返しますが、 argmax / argminその値があるインデックスを返します。 「最高血圧の患者は誰?」「最低SpO2の時刻は?」のような場面で便利です。 axis 指定の規則は mean などと同じです。

sample_3.py
Ctrl+Enter
出力

🤖 AI用語メモ — 「予測クラスの決定」とは?
画像分類などのAIモデルは、各クラスに対する 確率 を出力します(例: 3クラス分類なら3つの確率)。 最終的な予測ラベルは 「最も確率が高いクラスのインデックス」 を選ぶことで決まります。 これを実装するのが probs.argmax(axis=1) です。AI推論の最後の一行で必ず登場するパターンです。

5. 練習問題

問題 1

検査項目ごと・患者ごとに平均を求めよう

以下の (5, 3) 配列(5人 × 3項目: SBP, 心拍, 体温)から、 ① 各項目の平均(3つの値)② 各患者の平均(5つの値) を計算してください。

exercise_1.py
出力
ヒントを見る(答え+解説)
import numpy as np

data = np.array([
    [120, 72, 36.5],
    [135, 88, 37.2],
    [125, 75, 36.8],
    [150, 95, 37.5],
    [128, 80, 36.7]
])

# 各項目の平均(3つ)を計算してください
col_mean = data.mean(axis=0)

# 各患者の平均(5つ)を計算してください
row_mean = data.mean(axis=1)

print("項目ごとの平均:", col_mean.round(2))   # [131.6  82.   36.94]
print("患者ごとの平均:", row_mean.round(2))   # [76.17 86.73 78.93 94.17 81.57]

axis=0 は「行を潰す」= 各列の集計、axis=1 は「列を潰す」= 各行の集計。「axisで指定した軸が消える」と覚えれば迷いません。

問題 2

最高血圧の患者を特定しよう

以下の sbp_data = np.array([128, 142, 135, 158, 120, 145])(6人のSBP)から、 最も血圧が高い患者のインデックスと値を表示してください。

exercise_2.py
出力
ヒントを見る(答え+解説)
import numpy as np

sbp_data = np.array([128, 142, 135, 158, 120, 145])

# 最高血圧の患者のインデックスを取得してください
max_idx = sbp_data.argmax()

# その患者の血圧値を取得してください
max_val = sbp_data.max()
# 代替: max_val = sbp_data[max_idx]

print(f"最高血圧の患者: インデックス {max_idx} (値 {max_val} mmHg)")
# → 最高血圧の患者: インデックス 3 (値 158 mmHg)

argmax() は最大値の 位置(インデックス)を返します。「最も◯◯な患者は誰?」を特定する操作で頻出のパターンです。

問題 3

AIの予測クラスを決定しよう

AIモデルが出力した 4サンプル × 3クラス の予測確率 probs から、 各サンプルの予測クラス(最も確率が高いクラスのインデックス)を取得してください。

exercise_3.py
出力
ヒントを見る(答え+解説)
import numpy as np

probs = np.array([
    [0.85, 0.10, 0.05],
    [0.20, 0.65, 0.15],
    [0.10, 0.25, 0.65],
    [0.40, 0.45, 0.15]
])

# 各サンプルの予測クラスを取得してください
pred = probs.argmax(axis=1)

print("予測クラス:", pred)   # [0 1 2 1]

axis=1 で「各行(サンプル)内での最大の列(クラス)」を取得します。AIモデルの推論ループの最後の1行で必ず登場するパターンです。「サンプルごとに集計する」ので axis=1 を使う、と理解しましょう。

6. まとめ

このレッスンのポイント

  • axis=0 = 行を潰す = 各列の集計(特徴量ごと)
  • axis=1 = 列を潰す = 各行の集計(サンプルごと)
  • 「axisで指定した軸が消える」と覚えるのが最強の覚え方
  • keepdims=True で潰れた軸をサイズ1のまま残せる(次レッスンのブロードキャストで活用)
  • argmax / argmin位置を返す。AI予測クラスの決定で頻出

自由に試してみましょう:

free_practice.py
出力

完了するとコース一覧に進捗が記録されます