目次
はじめに
Pythonを実務で使い初めて3年。
生成AIやネットのコードを使えば動く。
でも、コードを“理解して書く”段階に進むと、手が止まる瞬間がありました。
自動化では「動けばいい」だったのが、
機械学習やデータ分析では「なぜそう書くのか」を理解しないと応用が効きません。
この記事では、生成AIやコピペに頼っていた当時の私が、
各処理の文法とロジックをつなぎ直し、自分の言葉で説明できるようになるまでを整理します。
データ前処理の全体像
- 配列の生成(np.array, np.zeros, np.random …)
- 形状の変換(reshape, flatten, ravel)
- 要素アクセス・集計(スライシング、sum(axis=…))
- 結合と積(演算)(ブロードキャスト、concatenate, stack, dot)
1. 配列の生成と基本構造の確認
1-1. 1次元配列を作る
文法構文
import numpy as np
array = np.array([1, 2, 3, 4])
print(array) # [1 2 3 4]解説(ロジック)
- np.array(list) で NumPy配列(ndarray) を作成。
1-2. ゼロ配列(zeros)
文法構文
array = np.zeros(10).reshape(2, 5)
print(array)
# [[0. 0. 0. 0. 0.]
# [0. 0. 0. 0. 0.]]1-3. 一様乱数(0〜1)(random.rand)
文法構文
array = np.random.rand(3, 4)
print(array) # 3行4列の0~1の乱数解説(ロジック)
- 疑似乱数。再現性が必要なら np.random.seed(123) を先に呼ぶ。
1-4. 配列の性質を確認する(shape・ndim・size)
文法構文
array = np.array([[1, 2, 4],
[8, 16, 32]])
print(array.shape) # (2, 3)
print(array.ndim) # 2
print(array.size) # 6💡 補足
| 属性 | 意味 | 例 |
|---|---|---|
| shape | 各次元のサイズ | (行, 列) |
| ndim | 次元の数 | 2(2次元) |
| size | 全要素数 | 6 |
2. 配列の形状の変換
2-1. 1次元→2次元に変換(reshape)
文法構文
array = np.array([1, 2, 3, 4, 5, 6]).reshape(2, 3)
print(array)
# [[1 2 3]
# [4 5 6]]解説(ロジック)
- reshape(行, 列) は 要素数が一致している必要あり(ここでは 6 = 2×3)。
2-2. 2次元→1次元(flatten / ravel)
文法構文
arr2d = np.array([[1, 2, 4],
[8, 16, 32]])
flat_copy = arr2d.flatten() # コピー
flat_view = arr2d.ravel() # ビュー(参照)
print(flat_copy) # [ 1 2 4 8 16 32]解説(ロジック)
- flatten() は コピー(元を変えない)
- ravel() は 参照(元配列の変更が波及することがある)
3. 要素アクセス&スライシング(要素確認)
3-1. スライス・インデックスで取り出す
文法構文
array = np.arange(1, 10).reshape(3, 3)
# [[1 2 3]
# [4 5 6]
# [7 8 9]]
print(array[1, 0]) # 2行1列 → 4
print(array[0:2, :]) # 先頭2行すべて
print(array[:, 1]) # 全行の2列目 → [2 5 8]
print(array[array % 2 == 0]) # 偶数だけ抽出 → [2 4 6 8]解説(ロジック)
- 行が先・列が後(array[row, col])。ブールインデックスで条件抽出。
3-2. 行方向・列方向の合計(sum(axis=…))
文法構文
array = np.arange(1, 7).reshape(2, 3)
print(array)
# [[1 2 3]
# [4 5 6]]
sum_cols = np.sum(array, axis=0) # 列ごと
print(sum_cols) # [5 7 9]
sum_rows = np.sum(array, axis=1) # 行ごと
print(sum_rows) # [ 6 15]解説(ロジック)
- axis=0 は 縦に畳む(列方向集計)
- axis=1 は 横に畳む(行方向集計)
4. 結合と積(演算)(ブロードキャスト、concatenate, stack, dot)
4-1. ブロードキャスト(broadcasting)
文法構文
スカラー加算
A = np.arange(1, 7).reshape(2, 3) # [[1 2 3],[4 5 6]]
print(A + 1)
# [[2 3 4]
# [5 6 7]]列ベクトル減算(形を揃えずに列方向へ適用)
v = np.array([1, 2, 3])
print(A - v)
# [[0 0 0]
# [3 3 3]]線形結合
print(3*A - 2*v)
# [[ 1 2 3]
# [10 11 12]]解説(ロジック)
- 右端の次元から形を照合。サイズ1は繰り返し可能。
4-2. 配列の結合:concatenate と stack
文法構文
concatenate(既存軸につなぐ:次元数は増えない)
a = np.array([1, 2, 4])
b = np.array([8, 16, 32])
c = np.concatenate([a, b]) # [ 1 2 4 8 16 32]stack(新しい軸を増やして積む:次元数が1つ増える)
s = np.stack([a, b], axis=0)
# [[ 1 2 4]
# [ 8 16 32]]
# shape: (2, 3)4-3. 行列の積(内積:dot / @)
文法構文
A = np.arange(1, 7).reshape(2, 3) # shape (2,3)
B = np.arange(1, 7).reshape(3, 2) # shape (3,2)
print(A)
print()
print(B)
print()
print(np.dot(A, B)) # あるいは A @ B解説(ロジック)
- 形 (m, n) · (n, p) → (m, p)
- dot product(ドット積)=内積。特徴合成や射影に使う。
付録:よくある落とし穴(Quick Tips)
- reshape は要素数一致が必須。合わないとエラー。
- flatten と ravel:コピーか参照かで使い分け。
- axis の向き:axis=0 は列方向集約、axis=1 は行方向集約。
- append より concatenate 推奨:多次元でも軸指定で安全。
- ブロードキャスト:右端次元から照合、サイズ1は繰り返しOK。
文法とロジック対応表
| ステップ | 主な構文 | 意図するロジック |
|---|---|---|
| 配列の生成 | np.array, np.zeros, np.random | データ容器を用意 |
| 形状の変換 | reshape, flatten/ravel | 学習器が扱いやすい形に整える |
| 要素アクセス・集計 | A[i,j], スライス, ブール, sum(axis) | 欲しい部分抽出と軸方向集計 |
| 結合 | concatenate, stack | 既存軸につなぐ / 新軸を増やす |
| 演算 | ブロードキャスト | 形を合わせず要素ごと演算 |
| 内積 | np.dot / @ | 行列積で特徴の合成・変換 |
まとめ
AIが助けてくれる時代に、
改めて「自分の手で考える」ことの大切さを感じています。
生成AIやコピペで動かすこと自体は悪くありません。
でも、それだけでは“理解したつもり”で止まってしまう。
小さな理解の積み重ねが、
やがて“再現できる力”を生み出していく。
その第一歩が、まさに今回の見直しなのかもしれません。
コメント