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

ブール選択と条件操作

このレッスンで学ぶこと

  • 比較演算子で配列のmask(bool配列)を作れる
  • arr[mask] 形式で条件に合う要素を抽出できる
  • np.where() で条件分岐の結果を一括生成できる
  • 条件付き代入で外れ値クリッピングなどができる

1. 比較演算子は bool 配列を返す

NumPy配列に比較演算子(><== など)を適用すると、 結果は 同じ shape の bool 配列 になります。これがNumPyの条件操作の出発点です。

sample_1.py
Ctrl+Enter
出力

and / or ではなく & / | を使う: 複数の条件を組み合わせるとき、Python の and / or は配列を扱えずエラーになります。 代わりに次の ビット演算子 を使ってください。

  • &  ...  and(かつ)
  • |  ...  or(または)
  • ~  ...  not(否定)

そして 各条件はカッコで囲む ことも徹底してください。

# ❌ エラー
(spo2 >= 95) and (spo2 <= 98)

# ✅ 正解
(spo2 >= 95) & (spo2 <= 98)

💡 bool 配列は集計でも便利: (spo2 < 95).sum() は「条件を満たす要素の数」、 .mean() は「全体に占める割合」を返します(True=1, False=0として平均する)。 データの基本傾向を1行で調べられる強力なテクニックです。

2. mask で要素を抽出する

bool配列を arr[mask] のように使うと、True の位置だけを取り出した新しい配列が返ります。 これを ブール選択(boolean indexing)マスク選択 と呼びます。

sample_2.py
Ctrl+Enter
出力

💡 ブール選択は「コピー」を返す: 前のレッスンでスライス(arr[1:3])はビューでしたが、 ブール選択(arr[mask])は 独立したコピー を返します。 つまり、low_spo2[0] = 0 としても元の spo2 は変わりません。 これは「True に該当する要素を集めて新しい配列を作る」という処理だからです。

🩺 医療AI文脈: 「特定条件の患者だけ抽出する」処理は前処理で頻出します。 例:patients[patients[:, 0] >= 65] は高齢者集団のサブセット作成、 data[labels == 1] は陽性患者だけ抽出、というように 「条件で行をフィルタする」 操作はAI学習データ作成の基本です。

3. np.where — 条件で値を切り替える

np.where(条件, true値, false値) は 「条件が真なら true値、偽なら false値」を 要素ごとに選んだ配列を返します。 if 文を for ループの中に書くのと同じことを、配列まるごとに一発でできます。

sample_3.py
Ctrl+Enter
出力

💡 np.where の使い分け:

  • 3引数版 np.where(cond, x, y):条件で値を切り替える(ラベル付け・条件付き計算)
  • 1引数版 np.where(cond):True のインデックスを返す(位置を知りたいとき)

機械学習では「確率を閾値で2値ラベルに変換」する処理で np.where(prob >= 0.5, 1, 0) がほぼ毎回登場します。

4. 条件付き代入とクリッピング

arr[条件] = 値 と書くと、条件を満たす要素だけを一括で更新できます。 外れ値の処理や前処理で頻出する書き方です。

また、値を「範囲内に収める」処理は np.clip(arr, min, max) で一発で書けます。

sample_4.py
Ctrl+Enter
出力

💡 「条件付き代入」と「np.where」の違い:

  • arr[cond] = 値元の配列を書き換える(破壊的)。一部だけ更新したいとき
  • np.where(cond, x, y)新しい配列を返す(非破壊的)。元を残したいとき
  • np.clip(arr, min, max):範囲内に丸める専用。np.where(arr<min, min, np.where(arr>max, max, arr)) と同じ

5. 練習問題

問題 1

異常値の検査値だけ抽出しよう

白血球数の配列 wbc = np.array([6200, 11500, 4800, 13000, 7100, 3200, 9000]) から、 正常範囲外(4000未満 または 10000超)の値だけを取り出してください。

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

wbc = np.array([6200, 11500, 4800, 13000, 7100, 3200, 9000])

# 正常範囲外(4000未満 または 10000超)の値だけを抽出してください
abnormal = wbc[(wbc < 4000) | (wbc > 10000)]

print("異常値:", abnormal)         # [11500 13000  3200]
print("異常値の数:", abnormal.size)   # 3

「または」は |(パイプ)を使います。各条件はカッコ (...) で囲むのを忘れずに。 and / or はNumPy配列では使えない点に注意してください。

問題 2

np.where で陽性・陰性ラベルを生成しよう

AIモデルの予測確率 probs = np.array([0.85, 0.42, 0.95, 0.30, 0.51, 0.12, 0.78]) について、 0.5以上なら 1 (陽性)、未満なら 0 (陰性) のラベル配列を np.where で生成してください。

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

probs = np.array([0.85, 0.42, 0.95, 0.30, 0.51, 0.12, 0.78])

# np.where で 0.5 以上なら 1、未満なら 0 のラベルを生成
labels = np.where(probs >= 0.5, 1, 0)

print("確率:", probs)
print("ラベル:", labels)   # [1 0 1 0 1 0 1]
print("陽性数:", labels.sum())   # 4

np.where(条件, true値, false値) で要素ごとに値を切り替えられます。これは機械学習の 「確率→二値ラベル変換」 でほぼ毎回登場するパターンです。(probs >= 0.5).astype(int) でも同じ結果になります。

問題 3

外れ値を範囲内にクリッピングしよう

収縮期血圧(SBP)の入力ミスを含む配列 sbp = np.array([120, 300, 90, 50, 250, 130, 70]) について、 正常範囲 60〜200 に収まるよう np.clip で丸めてください。

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

sbp = np.array([120, 300, 90, 50, 250, 130, 70])

# 60〜200 の範囲に収まるようクリッピングしてください
sbp_clipped = np.clip(sbp, 60, 200)

print("元の値:    ", sbp)
print("クリップ後:", sbp_clipped)   # [120 200  90  60 200 130  70]

np.clip(arr, min, max) は範囲外の値を端点に丸めます(300→200、50→60)。データ前処理での外れ値処理や、画像のピクセル値を 0〜255 に収める処理で頻出です。

6. まとめ

このレッスンのポイント

  • 比較演算子(>== など)は同じ shape の bool 配列を返す
  • 複合条件は &(and)・|(or)・~(not)。各条件はカッコで囲む
  • arr[mask] で True に該当する要素を抽出(コピーが返る)
  • np.where(条件, x, y) で要素ごとに値を切り替え(ラベル付けに頻出)
  • arr[条件] = 値 で条件付きの一括更新
  • np.clip(arr, min, max) で範囲内に収める

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

free_practice.py
出力

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