📚 背景知識(読んでから問題へ)
numpyは「数値の塊(配列)をまとめて操るための道具箱」です。Pythonのリストと違い、numpyの配列(ndarray)は全要素に対して一気に計算できるため、ループを書かずに高速処理できます。
今日のポイント:配列の形(shape)と変形(reshape)
shape = 配列の「縦×横」の構造
例: shape (3, 4) → 3行4列の表
arr.shape→ 配列の形を確認arr.reshape(行, 列)→ 形を変える(要素数は変えられない)arr.flatten()→ どんな形でも1次元に戻すnp.zeros(shape)/np.ones(shape)→ 0や1で埋めた配列を作るnp.arange(start, stop, step)→ Pythonのrange()のnumpy版
なぜKaggleで重要?
モデルに渡すデータは「行列」(2次元配列)の形であることがほとんどです。reshapeを使いこなせないと、エラーが多発します。特に画像データ(28×28ピクセルを784次元に変換するなど)では頻繁に登場します。
📝 問題
以下のタスクをnumpyを使って実装してください。
タスク:
- 0から23までの整数を含む1次元配列を作成する(要素数24)
- その配列を「4行6列」の2次元配列に変形する
- 変形後の配列の「2行目(インデックス1)」だけを取り出す
- 変形後の配列の「3列目(インデックス2)」だけを取り出す
- 変形後の配列の各行の合計を計算する(結果は4つの値)
- 変形後の配列の各列の平均を計算する(結果は6つの値)
出力例:
▶ 出力を見る
1次元配列: [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
4行6列:\n
[[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]
[12 13 14 15 16 17]
[18 19 20 21 22 23]]
2行目: [ 6 7 8 9 10 11]
3列目: [ 2 8 14 20]
各行の合計: [15 51 87 123]
各列の平均: [ 9. 10. 11. 12. 13. 14.]🔍 ヒント(段階的開示)
ヒント1(方向性)
numpyのarange、reshape、スライス([行, 列]記法)、sum、meanを組み合わせて解きます。まず1次元配列を作ってから変形しましょう。
ヒント2(アプローチ)
np.arange(24)で0〜23の配列を作成.reshape(4, 6)で形を変えるarr[1]またはarr[1, :]で2行目を取得arr[:, 2]で3列目を取得(「:」は「全て」の意味)arr.sum(axis=1)で行ごとの合計(axis=1 → 横方向に足す)arr.mean(axis=0)で列ごとの平均(axis=0 → 縦方向に平均)
ヒント3(コード骨格)
import numpy as np
# 1. 0から23の1次元配列
arr1d = np.arange(__)
# 2. 4行6列に変形
arr2d = arr1d.reshape(__, __)
# 3. 2行目(インデックス1)
row1 = arr2d[__, :]
# 4. 3列目(インデックス2)
col2 = arr2d[:, __]
# 5. 各行の合計
row_sum = arr2d.sum(axis=__)
# 6. 各列の平均
col_mean = arr2d.mean(axis=__)
✅ 模範解答
import numpy as np
# 1. 0から23までの整数(24要素)
arr1d = np.arange(24)
print("1次元配列:", arr1d)
# 2. 4行6列に変形
arr2d = arr1d.reshape(4, 6)
print("4行6列:")
print(arr2d)
# 3. 2行目(インデックス1)を取り出す
row1 = arr2d[1, :]
print("2行目:", row1)
# 4. 3列目(インデックス2)を取り出す
col2 = arr2d[:, 2]
print("3列目:", col2)
# 5. 各行の合計(axis=1: 横方向に足す)
row_sum = arr2d.sum(axis=1)
print("各行の合計:", row_sum)
# 6. 各列の平均(axis=0: 縦方向に平均)
col_mean = arr2d.mean(axis=0)
print("各列の平均:", col_mean)
🪜 Step-by-Step 解説
arr1d = np.arange(24)
# [ 0 1 2 3 ... 23]
np.arange(24) はPythonのrange(24)と同じ感覚で使えます。結果はリストではなくndarray(numpy配列)になります。
arr2d = arr1d.reshape(4, 6)
「24個の要素を4行6列に並べ直す」というイメージです。4×6=24なので要素数が合っています。要素数が合わないとエラーになります(例: reshape(3, 6) はNG、3×6=18≠24)。
row1 = arr2d[1, :] # または arr2d[1]
# [ 6 7 8 9 10 11]
[行番号, 列番号] の記法を使います。:は「全て」の意味。「1行目」は0から数えてインデックス1です。
col2 = arr2d[:, 2]
# [ 2 8 14 20]
[:, 2] は「全行の、2番目の列」という意味。Excelで特定の列を選ぶ感覚です。
row_sum = arr2d.sum(axis=1)
# [15 51 87 123]
axis=1は「列方向(横方向)に計算する」という意味。1行目: 0+1+2+3+4+5=15、2行目: 6+7+8+9+10+11=51、...
col_mean = arr2d.mean(axis=0)
# [ 9. 10. 11. 12. 13. 14.]
axis=0は「行方向(縦方向)に計算する」という意味。1列目: (0+6+12+18)/4=9.0。
📐 数学・統計の補足(文系向け)
axisの直感的な理解
axisは「どの方向に計算するか」を指定します:
axis=0 → 縦方向(行をまたいで計算)→ 結果は列の数だけ出る
axis=1 → 横方向(列をまたいで計算)→ 結果は行の数だけ出る
Excelで例えると:
axis=0でsum → 各列の縦合計(Excelの「列合計」)axis=1でsum → 各行の横合計(Excelの「行合計」)
最初は混乱しますが、「axis=0→縦、axis=1→横」と覚えると楽になります。
🏆 Kaggleでの実践的な使い方
画像データの変換(定番のreshape)
# MNISTデータセット(手書き数字)
# 元の形: (60000, 28, 28) → 6万枚の28×28ピクセル画像
# モデルに入力するため1次元に変換
X = images.reshape(60000, -1) # → (60000, 784)
# -1 は「残りの次元を自動計算」という意味
特徴量の集計
# コンペのデータで「ユーザーごとの購入額合計」を計算する際も
# 内部的にはaxis=0やaxis=1の考え方が使われています
user_total = purchase_matrix.sum(axis=1)
⚠️ よくある誤解・ミス
| 誤解・ミス | なぜ起こるか | 正しい理解 |
|---|---|---|
reshape後に元の配列も変わった | reshapeはビュー(参照)を返すことがある | 変更したくない場合は.copy()を使う |
axis=0とaxis=1を間違える | 日本語の「行・列」と英語の概念がずれる | 「0→縦、1→横」と暗記する |
arr[1]とarr[1, :]の違いが分からない | どちらも同じ結果だが記法が違う | どちらでもOK。2次元では[行, 列]記法を推奨 |
np.arangeとrangeの違い | 見た目が似ている | rangeはリスト、np.arangeはndarray。計算速度が全然違う |
🚀 次のステップ
- 発展:
np.concatenate・np.vstack・np.hstackで配列を結合する - 次回予告: pandas入門(DataFrame・Series)— Excelのように表形式データを操作する