📚 背景知識(読んでから問題へ)
numpyは「数値計算に特化したPythonライブラリ」です。Pythonのリストより圧倒的に速く、大量のデータを一括処理できます。
なぜKaggleでnumpyが重要か?
- データは基本的に「数値の塊(行列)」として扱われる
- pandasの内部もnumpyで動いている
- 特徴量エンジニアリングでベクトル演算(一括計算)が必須
今日のキーポイント: ブロードキャストと条件抽出
# ブロードキャスト: 配列全体に一括で演算
arr = np.array([1, 2, 3, 4, 5])
arr * 2 → [2, 4, 6, 8, 10] # 全要素に×2を一括適用
# 条件抽出(ブーリアンインデックス)
arr[arr > 3] → [4, 5] # 条件を満たす要素だけ取り出す
これは「Excelのフィルタ機能」をコードで書いているイメージです。
📝 問題
以下のコードを読んで、scores 配列に対する処理を完成させてください。
import numpy as np
# あるクラスの試験スコア(100点満点)
scores = np.array([55, 72, 88, 43, 91, 67, 34, 79, 85, 60])
問い1
scores の平均点、最高点、最低点を求めてください。
問い2
合格ライン(60点以上)の人数を求めてください。
(ヒント: True/False の配列は sum() で合計できます)
問い3
全員のスコアを「偏差値」に変換してください。
偏差値の計算式:
偏差値 = (得点 - 平均点) / 標準偏差 × 10 + 50
問い4
偏差値が55以上の人のスコア(元のscores)を取り出してください。
🔍 ヒント(段階的開示)
ヒント1(方向性)
- 問い1: np の関数を使えば1行で書けます(
np.mean,np.max,np.min) - 問い2:
scores >= 60で True/False 配列が作れます - 問い3: 標準偏差は
np.std()で求められます - 問い4: 問い3で作った偏差値配列を条件に使います
ヒント2(アプローチ)
# 問い2のヒント
mask = scores >= 60 # [False, True, True, False, True, ...]
print(mask.sum()) # Trueの数 = 合格者数
# 問い4のヒント(ブーリアンインデックス)
hensa = ... # 問い3で計算
scores[hensa >= 55] # 偏差値55以上の人のscores
ヒント3(コード骨格)
# 問い1
mean_score = np.mean(scores)
max_score = np._____(scores)
min_score = np._____(scores)
# 問い2
pass_count = (scores >= 60).sum()
# 問い3
std_score = np.std(scores)
hensa = (scores - mean_score) / std_score * 10 + 50
# 問い4
high_scorers = scores[hensa >= 55]
✅ 模範解答
import numpy as np
scores = np.array([55, 72, 88, 43, 91, 67, 34, 79, 85, 60])
# 問い1: 基本統計
mean_score = np.mean(scores)
max_score = np.max(scores)
min_score = np.min(scores)
print(f"平均: {mean_score:.1f}, 最高: {max_score}, 最低: {min_score}")
# → 平均: 67.4, 最高: 91, 最低: 34
# 問い2: 合格者数
pass_count = (scores >= 60).sum()
print(f"合格者数: {pass_count}人")
# → 合格者数: 7人
# 問い3: 偏差値変換
std_score = np.std(scores)
hensa = (scores - mean_score) / std_score * 10 + 50
print("偏差値:", np.round(hensa, 1))
# → 偏差値: [46.1 52.3 60.9 40.5 63.9 49.9 37.4 54.9 59.6 49.4]
# 問い4: 偏差値55以上のスコアを取り出す
high_scorers = scores[hensa >= 55]
print(f"偏差値55以上のスコア: {high_scorers}")
# → 偏差値55以上のスコア: [88 91 79 85]
🪜 Step-by-Step 解説
1
基本統計関数
np.mean(scores) # 平均 = 全要素を足して個数で割る
np.max(scores) # 最大値
np.min(scores) # 最小値
np.std(scores) # 標準偏差(データのバラツキ具合)
numpyはこれらを「全要素に対して一括」で計算します。Pythonのループは不要。
2
ブーリアンインデックス(条件抽出)
mask = scores >= 60
# → array([False, True, True, False, True, ...])
mask.sum()
# → True=1, False=0 として合計 = 合格者数
scores >= 60 は「各要素が60以上かどうか」をTrue/Falseで返します。.sum() でTrueの個数が合格者数になります。
3
偏差値変換(ブロードキャスト)
hensa = (scores - mean_score) / std_score * 10 + 50
scores - mean_score: 全要素から平均を引く(ブロードキャスト)/ std_score: 全要素を標準偏差で割る* 10 + 50: スケール変換
この1行でリスト全体を一括変換。Pythonのforループなら10回の計算が必要なところ、1回で済みます。
4
条件に別の配列を使ったインデックス
scores[hensa >= 55]
hensa >= 55 という True/False 配列を scores のインデックスに使っています。「偏差値が55以上の要素番号」の位置にある scores の値だけ取り出されます。
📐 数学・統計の補足(文系向け)
標準偏差(std)とは?
- データがどれくらいバラついているかを表す数値
- バラつきが大きい → stdが大きい(クラスの実力差が大きい)
- バラつきが小さい → stdが小さい(実力が均一なクラス)
偏差値とは?
- 平均を50、バラつきを10に変換する「共通のものさし」
- 偏差値70 → 平均より2標準偏差分上(上位約2.3%)
- 偏差値50 → ちょうど平均
なぜ ×10 + 50 するの?
(得点 - 平均) / 標準偏差だけだと、平均が0、標準偏差が1の値(zスコア)になる- 日本の偏差値に変換するため×10+50にする慣習
🏆 Kaggleでの実践的な使い方
特徴量の標準化(StandardScaler)
機械学習モデルに渡す前に、特徴量のスケールを揃えるのが一般的です。
# Kaggleでよく使う標準化(偏差値変換と同じ発想)
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X_train)
内部では (X - mean) / std を計算しており、今日の偏差値計算と同じです。
ブーリアンインデックスでの外れ値除去
# 3σ(シグマ)を超える外れ値を除去するKaggleの定石
z_score = (scores - np.mean(scores)) / np.std(scores)
scores_clean = scores[np.abs(z_score) < 3]
⚠️ よくある誤解・ミス
| 誤解・ミス | なぜ起こるか | 正しい理解 | |
|---|---|---|---|
np.std() の結果がPandasと違う | pandasはデフォルトで不偏標準偏差(n-1)、numpyは母標準偏差(n)を使う | np.std(scores, ddof=1) でpandasと一致する | |
| ブーリアン配列で元の長さと違う結果 | 条件抽出は条件を満たした要素だけを返す(フィルタ結果) | 意図通り。フィルタされた配列が返る | |
hensa >= 55 の括弧を忘れる | 演算子の優先順位 | scores[hensa >= 55] は正しく動くが、複合条件は &/` | ` と括弧が必要 |
🚀 次のステップ
- 発展: 2次元配列(行列)の操作 —
np.reshape,np.dot, 行・列方向の集計(axis=0/1) - 次回予告: pandas入門(DataFrame・Series) — Kaggleで最も使うデータ操作ライブラリへ