Python | ファイル・OS 操作:NumPy の reshape

Python Python
スポンサーリンク

概要(reshapeは「要素数はそのまま、形だけ変える」ための基本テク)

NumPy の reshape は、配列の総要素数を変えずに「形(次元・行数・列数)」だけを変える関数です。処理の型は「配列を作る→shapeを確認→reshapeで目的の形へ→必要なら転置や結合で整える」。重要ポイントは「-1で自動計算」「view と copy の違い」「reshape と転置・平坦化との区別」「列優先(Fortran順)指定」です。


基本の使い方(ここが重要)

1次元から2次元・3次元へ変形

import numpy as np

a = np.arange(6)             # [0 1 2 3 4 5]
b = a.reshape(2, 3)          # 2行3列
c = a.reshape(1, 2, 3)       # 3次元(1×2×3)
print(b.shape, c.shape)      # (2, 3) (1, 2, 3)
Python

総要素数は常に同じ(この例は6)。一致しない形を指定するとエラーになります。

-1で次元を自動計算(最重要テク)

a = np.arange(12)            # 12個
print(a.reshape(3, -1))      # 3行×?列 → 4列に自動決定
print(a.reshape(-1, 6))      # ?行×6列 → 2行に自動決定
Python

-1は「この次元は自動で計算して」。複数の -1 は不可(どちらも自動にすると曖昧)。

2次元を平坦化(1次元へ)

m = np.array([[1, 2, 3],
              [4, 5, 6]])
print(m.reshape(-1))         # → [1 2 3 4 5 6]
Python

「行列を並べ直して1本にする」最短形。連続メモリなら高速です。


深掘りポイント(view/copy・転置・順序・安全設計)

reshapeは多くの場合「view(共有)」になる

a = np.arange(6)
b = a.reshape(2, 3)   # bはaの並び替えビューになりやすい
b[0, 0] = 99
print(a)              # → [99 1 2 3 4 5] 元にも反映(共有)
Python

元を変えたくないなら、reshapeの直後に copy() を付けて「完全なコピー」にします。

b = a.reshape(2, 3).copy()
Python

reshape と転置(T)は別物(入れ替えか、並べ替えか)

m = np.arange(6).reshape(2, 3)  # [[0,1,2],[3,4,5]]
print(m.T)                      # 転置(2×3 → 3×2)
Python
  • reshape: 総要素数を保ったまま「形」を変える
  • 転置: 軸の入れ替え(行⇔列)。必要に応じて組み合わせます。

列優先(Fortran順)での reshape

a = np.arange(6)
print(a.reshape(2, 3, order="F"))  # 列(縦)を優先して並べる
Python

デフォルトは行優先(C順)。外部ツールや行列演算の都合で列優先を使いたい時に指定します。

形の整合性チェックを癖にする(要素数が合わないと失敗)

a = np.arange(10)
# a.reshape(3, 4)  # 10→12は不可(ValueError)
Python

最初に「a.size と新形状の積」を頭でチェックしておくと事故が減ります。


実務での使いどころ(画像・時系列バッチ・列結合)

画像の整形(28×28 → ベクトル、逆も)

img = np.arange(28*28)                 # 例:28×28の画像
vec = img.reshape(-1)                   # 学習用に1次元へ
img2d = img.reshape(28, 28)             # 表示用に2次元へ戻す
Python

「学習時はベクトル、表示時は2D」の往復が定番です。

バッチ処理(N×特徴数へ整形)

raw = np.arange(60)                     # 例:60要素
batch = raw.reshape(-1, 5)              # 行数自動、5列(特徴数)
print(batch.shape)                      # → (12, 5)
Python

「1レコードの特徴数」を列数に、行数は -1 で自動計算するのが最短です。

複数列をまとめて計算→元形へ戻す

xy = np.stack([np.arange(6), np.arange(6)*10], axis=1)  # 6×2
flat = xy.reshape(-1)                                    # 12要素へ
flat = flat + 1                                          # まとめて処理
xy2 = flat.reshape(xy.shape)                             # 6×2へ復元
Python

「まとめて処理 → 元の形へ復元」が安全で読みやすいパターン。


よくある落とし穴(多重 -1・非連続メモリ・ravel/flatten)

複数の -1 は使えない

a = np.arange(12)
# a.reshape(-1, -1, 3)  # どちらも自動は不可(曖昧)
Python

-1 は必ず1つだけ。

非連続メモリ(スライス)からの reshape は copy になることがある

a = np.arange(10)
s = a[::2]                 # ストライド付き(非連続)
b = s.reshape(5, 1)        # 必要に応じて内部でコピーが発生
Python

「ビューかコピーか」は元配列のメモリ配置次第。共有を期待するなら連続メモリのまま扱うか、明示的に copy を使う。

ravel と flatten の違い(速度・共有)

m = np.arange(6).reshape(2, 3)
r = m.ravel()     # 可能ならビュー(共有)で平坦化
f = m.flatten()   # 常にコピー(独立)
Python

元を守りたいなら flatten、速度・省メモリを優先なら ravel。


例題で身につける(定番から一歩先まで)

例題1:要素数チェックと -1 の活用

import numpy as np
a = np.arange(24)
print(a.size)               # 24
print(a.reshape(4, -1))     # 4×6
print(a.reshape(-1, 8))     # 3×8
Python

例題2:転置を絡めた形変換(列→行へ)

import numpy as np
col = np.arange(6).reshape(6, 1)  # 6×1
row = col.T.reshape(-1)           # 1×6 → 1次元
print(row)
Python

例題3:Fortran順の挙動確認

import numpy as np
a = np.arange(6)
c = a.reshape(2, 3)               # C順
f = a.reshape(2, 3, order="F")    # F順
print(c)
print(f)
Python

例題4:安全なコピーで元を保護

import numpy as np
a = np.arange(9)
b = a.reshape(3, 3).copy()   # 独立
b[0, 0] = 99
print(a[0])                  # 0(元は無傷)
Python

まとめ

reshape は「総要素数は固定、形だけ変える」ための核機能です。-1 で自動計算、転置(T)と組み合わせ、必要なら order=”F” を使い分ける。ビューになりやすいので「元を守りたいなら copy」、平坦化は ravel(共有)か flatten(コピー)を選ぶ。要素数の整合を常に確認し、画像・バッチ・列結合の整形に活用すれば、初心者でも短く・安全に“形を操る”コードが書けます。

タイトルとURLをコピーしました