Day 036 — numpy入門(配列操作・数値計算)

2026-05-15 白 / Phase 1 理論 numpy入門(配列操作・数値計算)

📚 背景知識(読んでから問題へ)

numpyの「次元」を身近な例えで理解する

numpyの配列(ndarray)は「箱の入れ子構造」で考えると分かりやすいです。

  • 0次元(スカラー): 数値1個。例: 42
  • 1次元(ベクトル): 数字が一列に並んだもの。例: [1, 2, 3, 4, 5](テストの点数リスト)
  • 2次元(行列): 表(スプレッドシートのイメージ)。例: 5人×3科目の成績表
  • 3次元: 表が複数枚重なったもの。例: 月別×5人×3科目の成績(12枚の表が重なっている)

なぜ「形状(shape)」が重要か

numpyで最も大事な概念が shape(形状) です。データが何行×何列(×何層)で構成されているかを表します。

array.shape  →  (行数, 列数)  →  例: (100, 5) は100行5列

Kaggleのデータ処理では、配列の形状が一致していないと計算エラーが発生します。shape を常に意識することが、バグを防ぐ第一歩です。

ブロードキャストとは何か

numpyには「ブロードキャスト」という自動拡張機能があります。

例え: 「5人全員のテストの点数に10点加算する」とき、わざわざ [10, 10, 10, 10, 10] を用意しなくても scores + 10 と書くだけで全員に加算されます。これがブロードキャストです。

scores = np.array([70, 80, 60, 90, 75])
scores + 10  # → array([80, 90, 70, 100, 85])

📝 問題

以下の numpyに関する4つの概念説明を読み、それぞれが 正しい(○)誤り(×) かを答えなさい。誤りの場合は正しい説明を述べなさい。

【概念A】

np.array([1, 2, 3])np.array([[1, 2, 3]]) は、格納されている数値は同じなので、.shape も同じ (3,) になる。

【概念B】

np.zeros((3, 4)) は、すべての要素が 0 の「3行4列」の2次元配列を作成する。

【概念C】

numpyの配列は、Python のリストと違い、1つの配列の中に整数と文字列を混在させることができない。これを「均一なデータ型(dtype)を持つ」という。

【概念D】

np.arange(1, 10, 2) は、[1, 3, 5, 7, 9, 10] という配列を返す。


🔍 ヒント(段階的開示)

ヒント1(方向性)

各概念について、実際にPythonで動かして確認するのが一番確実です。特にshapeは .shape で確認できます。

ヒント2(アプローチ)
  • 【概念A】: [1, 2, 3] は1次元、[[1, 2, 3]] は2次元(外側の [] がもう1層ある)
  • 【概念B】: np.zeros の引数はタプルで (行, 列) の順
  • 【概念C】: numpyのdtype(データ型)の特性を思い出してください
  • 【概念D】: np.arange(start, stop, step)stop は含まれるか含まれないかに注意
ヒント3(コード骨格)
import numpy as np

# 概念A の確認
a1 = np.array([1, 2, 3])
a2 = np.array([[1, 2, 3]])
print(a1.shape)  # ?
print(a2.shape)  # ?

# 概念D の確認
print(np.arange(1, 10, 2))  # ?

模範解答

【概念A】× 誤り

np.array([1, 2, 3]).shape(3,) だが、np.array([[1, 2, 3]]).shape(1, 3) になる。外側にもう1つ [] があることで「1行3列の2次元配列」になる。

【概念B】○ 正しい

np.zeros((3, 4)) は 3行4列の全ゼロ配列を作成する。

【概念C】○ 正しい

numpyの配列は1つのdtype(データ型)しか持てない。整数と文字列を混在させると、Pythonが自動的に全要素を文字列型( など)に変換してしまう。

【概念D】× 誤り

np.arange(1, 10, 2)[1, 3, 5, 7, 9] を返す(10は含まれない)。np.arangestop含まれない(Pythonの range() と同じルール)。

import numpy as np

# 確認コード
print(np.array([1, 2, 3]).shape)       # (3,)
print(np.array([[1, 2, 3]]).shape)     # (1, 3)

print(np.zeros((3, 4)))
# [[0. 0. 0. 0.]
#  [0. 0. 0. 0.]
#  [0. 0. 0. 0.]]

mixed = np.array([1, 2, "hello"])
print(mixed.dtype)   # 

🪜 Step-by-Step 解説

1
次元の違いを視覚的に理解する(概念A)
import numpy as np

a1 = np.array([1, 2, 3])
a2 = np.array([[1, 2, 3]])

print(a1.ndim, a1.shape)  # 1次元, (3,)
print(a2.ndim, a2.shape)  # 2次元, (1, 3)

[1, 2, 3] → 1次元(単なる数字の列)

[[1, 2, 3]] → 2次元(1行3列の表)

なぜこれが重要か: Kaggleのデータは2次元(表形式)が基本です。モデルに渡すとき (N,)(N, 1) の違いでエラーになることがよくあります。

2
np.zeros / np.ones の使い方(概念B)
zeros_matrix = np.zeros((3, 4))   # 3行4列の全ゼロ
ones_matrix  = np.ones((2, 5))    # 2行5列の全1
eye_matrix   = np.eye(3)          # 3×3の単位行列(対角が1)

print(zeros_matrix.shape)  # (3, 4)

使い道: 初期値の配列を用意したり、マスク処理(特定箇所だけ0/1にする)に使います。

3
dtypeの均一性(概念C)
# Pythonリストは混在OK
py_list = [1, 2, "hello"]  # エラーにならない

# numpyは全部同じ型に変換される
np_arr = np.array([1, 2, "hello"])
print(np_arr)        # ['1' '2' 'hello']  ← 数値が文字列になった!
print(np_arr.dtype)  # 

注意: 数値データに欠損値(NaN)を入れると自動的に float64 に変換されます。

4
arangeとlinspaceの使い分け(概念D)
# np.arange: ステップ幅を指定(stopは含まない)
print(np.arange(1, 10, 2))    # [1 3 5 7 9]
print(np.arange(0, 1, 0.25))  # [0.   0.25 0.5  0.75]

# np.linspace: 個数を指定(stopを含む)
print(np.linspace(0, 1, 5))   # [0.   0.25 0.5  0.75 1.  ]

使い分け: グラフの軸を作るときは linspace(「0から1まで100点均等に」)、ループの代替は arange(「0から9まで2刻みで」)が多い。


📐 数学・統計の補足(文系向け)

「行列」を怖がらなくていい

「行列」と聞くと難しそうですが、Kaggleで使う場面のほとんどは「表(スプレッドシート)」のことです。

  • 行 = サンプル(1人のデータ)
  • 列 = 特徴量(年齢・性別・価格など)

(1000, 15) の行列 = 1000人分のデータ、各人に15個の情報がある表。

これだけ理解していれば、numpyの行列操作の意味が直感的に分かります。

shapeとdtypeは「配列の身分証明書」

numpyで何かうまくいかないとき、まず確認すること:

print(array.shape)   # 形状確認
print(array.dtype)   # 型確認
print(array.ndim)    # 次元確認

これを習慣にするだけで、デバッグ時間が大幅に短縮されます。


🏆 Kaggleでの実践的な使い方

1. 特徴量の形状チェック(前処理の基本)

import numpy as np
import pandas as pd

df = pd.read_csv("train.csv")
X = df.drop("target", axis=1).values  # numpyに変換

print(X.shape)   # (891, 10) → 891サンプル、10特徴量
print(X.dtype)   # データ型確認

2. モデルへの入力形状の注意

scikit-learnのモデルは (nsamples, nfeatures) を期待します。1次元配列を渡すとエラーになります:

# NG: 1次元
model.fit(np.array([1, 2, 3]), y)  # エラー

# OK: 2次元に変換
model.fit(np.array([[1], [2], [3]]), y)
# または
model.fit(X.reshape(-1, 1), y)

3. ブロードキャストでの特徴量正規化

X = np.array([[170, 60], [165, 55], [180, 70]])  # 身長・体重データ
mean = X.mean(axis=0)   # 列ごとの平均: [171.67, 61.67]
std  = X.std(axis=0)    # 列ごとの標準偏差

X_normalized = (X - mean) / std  # ブロードキャストで全行に適用

⚠️ よくある誤解・ミス

誤解・ミスなぜ起こるか正しい理解
[1,2,3][[1,2,3]] が同じと思う見た目が似ているからshapeが (3,) vs (1,3) で別物。モデルに渡すとエラーの原因になる
np.arange(1, 10) で10が含まれると思う「1から10まで」という日本語の感覚からstopは含まれない。Pythonのrange()と同じルール
整数配列にNaNを入れようとする欠損値を扱う際に起こるNaNはfloat型なので、float64の配列にしか入れられない
array.shape を忘れてデバッグするエラーメッセージが分かりにくい処理の各ステップでshapeをprintする習慣をつける

🚀 次のステップ

  • 発展: numpyのスライシング(X[0:5, 2:4] のように2次元配列の一部を取り出す方法)とfancy indexing(X[[0, 2, 4]] のようにインデックスの配列で取り出す方法)
  • 次回予告: pandas入門(DataFrame・Series)— numpyの次はKaggleで最も使う表形式データ操作ツールへ

🎯 自己評価

自分の回答

気づき・メモ