1. 比較演算子は bool 配列を返す
NumPy配列に比較演算子(>・<・== など)を適用すると、
結果は 同じ shape の bool 配列 になります。これがNumPyの条件操作の出発点です。
⚠ 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) や マスク選択 と呼びます。
💡 ブール選択は「コピー」を返す:
前のレッスンでスライス(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 ループの中に書くのと同じことを、配列まるごとに一発でできます。
💡 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) で一発で書けます。
💡 「条件付き代入」と「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. 練習問題
異常値の検査値だけ抽出しよう
白血球数の配列 wbc = np.array([6200, 11500, 4800, 13000, 7100, 3200, 9000]) から、
正常範囲外(4000未満 または 10000超)の値だけを取り出してください。
ヒントを見る(答え+解説)
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配列では使えない点に注意してください。
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 で生成してください。
ヒントを見る(答え+解説)
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) でも同じ結果になります。
外れ値を範囲内にクリッピングしよう
収縮期血圧(SBP)の入力ミスを含む配列 sbp = np.array([120, 300, 90, 50, 250, 130, 70]) について、
正常範囲 60〜200 に収まるよう np.clip で丸めてください。
ヒントを見る(答え+解説)
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)で範囲内に収める
自由に試してみましょう:
完了するとコース一覧に進捗が記録されます