【初心者必見】NumPyのreshapeメソッドの使い方まとめ

python

NumPyのreshape()メソッドは、配列(ndarray)の「形(行数・列数など)」を変更するための関数です。

データ分析・機械学習・画像処理など、あらゆる場面で「データの並び方を変えたい」ことはよくあります。そのときに活躍するのがこのreshape()です。

arr.reshape(行数, 列数)

この記事では、reshape()の基本構文、よくあるエラー、次元の自動計算、実務で使える応用テクニックまで説明します。

スポンサーリンク

reshapeの基本構文と使い方

基本の考え方

重要なポイント:

  • 元の配列の要素数は変えずに、形だけ変える
  • 中身のデータは同じで、並び方だけが変わる

基本構文

new_arr = arr.reshape(新しい形状)

例1:1次元から2次元への変換(6個 → 2行3列)

import numpy as np

# 1次元配列を作成
arr = np.array([1, 2, 3, 4, 5, 6])
print(f"元の配列: {arr}")
print(f"元の形状: {arr.shape}")  # 結果: (6,)

# 2行3列に変換
reshaped = arr.reshape(2, 3)
print("変換後の配列:")
print(reshaped)
# 結果:
# [[1 2 3]
#  [4 5 6]]
print(f"変換後の形状: {reshaped.shape}")  # 結果: (2, 3)

どうやって変換される?

元: [1, 2, 3, 4, 5, 6]
↓
変換後:
[[1, 2, 3],
 [4, 5, 6]]

左から順番に、指定した形に当てはめられます。

例2:1次元から3次元への変換

# 12個の要素を持つ配列
arr = np.arange(12)  # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
print(f"元の配列: {arr}")

# 2×3×2の3次元配列に変換
reshaped_3d = arr.reshape(2, 3, 2)
print("3次元に変換:")
print(reshaped_3d)
# 結果:
# [[[ 0  1]
#   [ 2  3]
#   [ 4  5]]
#  [[ 6  7]
#   [ 8  9]
#   [10 11]]]

例3:2次元から1次元への変換(平坦化)

# 2次元配列を作成
matrix = np.array([[1, 2, 3], [4, 5, 6]])
print("元の2次元配列:")
print(matrix)

# 1次元に変換
flattened = matrix.reshape(6)  # または matrix.reshape(-1)
print(f"1次元に変換: {flattened}")
# 結果: [1 2 3 4 5 6]

まとめ

  • reshape()は「要素数を保ったまま形状だけ変える」関数
  • 中身のデータの順番は保たれる

reshapeで自動的に次元数を計算(-1の使い方)

-1を使った自動計算

1つの次元を-1にすると、他の次元から自動的に計算されます!

import numpy as np

# 12個の要素を持つ配列
arr = np.arange(12)
print(f"元の配列: {arr}")

# 3行、列数は自動計算
result1 = arr.reshape(3, -1)
print(f"3行、列数自動: {result1.shape}")  # 結果: (3, 4)
print(result1)
# 結果:
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]

# 4行、列数は自動計算
result2 = arr.reshape(4, -1)
print(f"4行、列数自動: {result2.shape}")  # 結果: (4, 3)
print(result2)
# 結果:
# [[ 0  1  2]
#  [ 3  4  5]
#  [ 6  7  8]
#  [ 9 10 11]]

計算の仕組み:

  • 全要素数:12個
  • 3行指定 → 列数 = 12 ÷ 3 = 4列
  • 4行指定 → 列数 = 12 ÷ 4 = 3列

注意:複数の-1は使えない

# これはエラーになる
try:
    arr.reshape(-1, -1)  # ❌ ValueError
except ValueError as e:
    print(f"エラー: {e}")

理由: どちらも「おまかせ」だと、計算できないため

よく使うパターン

パターン1:flatten(1次元化)

matrix = np.array([[1, 2, 3], [4, 5, 6]])
flattened = matrix.reshape(-1)
print(f"1次元化: {flattened}")  # 結果: [1 2 3 4 5 6]

パターン2:列ベクトル化(縦一列に並べる)

arr = np.array([1, 2, 3, 4])
column_vector = arr.reshape(-1, 1)
print("列ベクトル:")
print(column_vector)
# 結果:
# [[1]
#  [2]
#  [3]
#  [4]]
print(f"形状: {column_vector.shape}")  # 結果: (4, 1)

パターン3:行ベクトル化(横一列に並べる)

arr = np.array([1, 2, 3, 4])
row_vector = arr.reshape(1, -1)
print("行ベクトル:")
print(row_vector)  # 結果: [[1 2 3 4]]
print(f"形状: {row_vector.shape}")  # 結果: (1, 4)

まとめ

  • -1はreshapeの「おまかせ指定」
  • 柔軟な形状変換にとても便利

よくあるエラーと対策

エラー1:reshapeできない数を指定

import numpy as np

# 10個の要素を持つ配列
arr = np.arange(10)
print(f"配列: {arr}")
print(f"要素数: {arr.size}")  # 結果: 10

try:
    # 3×4=12なので、10個の要素では作れない
    reshaped = arr.reshape(3, 4)
except ValueError as e:
    print(f"エラー: {e}")
    print("10個の要素を3×4(12個)には変形できません")

# 正しい例
correct_reshape = arr.reshape(2, 5)  # 2×5=10なのでOK
print("正しい変形:")
print(correct_reshape)

対策: 要素数を確認してから、掛け算が合う形状を指定する

def suggest_shapes(arr):
    """可能な形状を提案する関数"""
    size = arr.size
    print(f"要素数: {size}")
    print("可能な形状:")
    
    for i in range(1, size + 1):
        if size % i == 0:
            print(f"  {i}行 × {size // i}列")

# 使用例
arr = np.arange(12)
suggest_shapes(arr)
# 結果:
# 要素数: 12
# 可能な形状:
#   1行 × 12列
#   2行 × 6列
#   3行 × 4列
#   4行 × 3列
#   6行 × 2列
#   12行 × 1列

エラー2:reshape後の配列に代入し忘れ

import numpy as np

arr = np.array([1, 2, 3, 4, 5, 6])
print(f"元の形状: {arr.shape}")  # 結果: (6,)

# 間違い:代入していない
arr.reshape(2, 3)
print(f"reshapeした後の形状: {arr.shape}")  # 結果: (6,) ← 変わっていない!

# 正しい方法1:代入する
arr_reshaped = arr.reshape(2, 3)
print(f"正しく代入した形状: {arr_reshaped.shape}")  # 結果: (2, 3)

# 正しい方法2:元の変数に代入
arr = arr.reshape(2, 3)
print(f"元の変数に代入した形状: {arr.shape}")  # 結果: (2, 3)

重要なポイント: reshape()非破壊的な関数です。元の配列は変更せず、新しい配列を返します。

エラー3:転置と混同する

import numpy as np

# 2×3の配列
matrix = np.array([[1, 2, 3], [4, 5, 6]])
print("元の配列:")
print(matrix)
print(f"形状: {matrix.shape}")  # 結果: (2, 3)

# 間違い:行と列を入れ替えたいのにreshapeを使う
wrong = matrix.reshape(3, 2)
print("reshapeで3×2に変更:")
print(wrong)
# 結果:
# [[1 2]
#  [3 4]
#  [5 6]]

# 正しい:転置を使う
correct = matrix.T  # または matrix.transpose()
print("転置(正しい行列の入れ替え):")
print(correct)
# 結果:
# [[1 4]
#  [2 5]
#  [3 6]]
print(f"転置後の形状: {correct.shape}")  # 結果: (3, 2)

使い分け:

  • reshape:要素の順番を保ったまま形状変更
  • 転置(transpose):行と列を入れ替える

まとめ

  • エラーの原因はほとんどが「要素数が合わない or 代入忘れ
  • 転置が必要な場合は.Tを使う

実務でよくあるreshape活用例

活用例1:画像処理(28×28の画像を1次元ベクトルに)

import numpy as np

# 28×28の画像データ(手書き数字など)
image = np.random.randint(0, 256, size=(28, 28))
print(f"元の画像形状: {image.shape}")  # 結果: (28, 28)
print(f"画素数: {image.size}")  # 結果: 784

# 機械学習用に1次元ベクトルに変換
flattened_image = image.reshape(-1)
print(f"1次元化後の形状: {flattened_image.shape}")  # 結果: (784,)

# 複数の画像をまとめて処理
num_images = 100
images = np.random.randint(0, 256, size=(num_images, 28, 28))
print(f"複数画像の形状: {images.shape}")  # 結果: (100, 28, 28)

# 各画像を1次元化(100枚 × 784ピクセル)
flattened_images = images.reshape(num_images, -1)
print(f"一括1次元化後: {flattened_images.shape}")  # 結果: (100, 784)

活用例2:機械学習の特徴量整形

import numpy as np

# 時系列データの例(10日間 × 24時間 × 3つの測定値)
time_series = np.random.randn(10, 24, 3)
print(f"時系列データの形状: {time_series.shape}")  # 結果: (10, 24, 3)

# 機械学習用に2次元に変換(サンプル数 × 特徴数)
# 各日を1つのサンプルとして、24×3=72の特徴量に
X = time_series.reshape(10, -1)
print(f"特徴量行列の形状: {X.shape}")  # 結果: (10, 72)

# または、各時刻を1つのサンプルとして扱う場合
# 10×24=240のサンプル、各サンプルは3つの特徴量
X_hourly = time_series.reshape(-1, 3)
print(f"時刻ごとの特徴量: {X_hourly.shape}")  # 結果: (240, 3)

活用例3:CSVやExcelの行列整形

import numpy as np

# 長い1次元データを読み取った場合
csv_data = np.arange(1, 21)  # 1から20までのデータ
print(f"元のデータ: {csv_data}")

# 4行5列の表に整形
table = csv_data.reshape(4, 5)
print("表形式に整形:")
print(table)
# 結果:
# [[ 1  2  3  4  5]
#  [ 6  7  8  9 10]
#  [11 12 13 14 15]
#  [16 17 18 19 20]]

# カラム名をつけて表示(pandas風)
import pandas as pd
df = pd.DataFrame(table, columns=[f'列{i+1}' for i in range(5)])
print("DataFrame形式:")
print(df)

活用例4:3Dデータの可視化準備

import numpy as np

# 3次元データ(例:医療画像、気象データなど)
volume_data = np.random.randn(10, 10, 10)
print(f"3次元データ: {volume_data.shape}")

# 2次元スライスとして表示するために変形
# 各スライス(10×10)を横に並べて表示
slices_horizontal = volume_data.reshape(10, -1)
print(f"横並びスライス: {slices_horizontal.shape}")  # 結果: (10, 100)

# 各スライスを縦に並べて表示
slices_vertical = volume_data.transpose(2, 0, 1).reshape(-1, 10)
print(f"縦並びスライス: {slices_vertical.shape}")  # 結果: (100, 10)

活用例5:バッチ処理でのデータ整形

import numpy as np

# ニューラルネットワーク用のデータ準備
# バッチサイズ32、シーケンス長20、特徴量10
batch_data = np.random.randn(32, 20, 10)
print(f"バッチデータ: {batch_data.shape}")

# RNN用に2次元に変換(全時刻をまとめて処理)
rnn_input = batch_data.reshape(-1, 10)
print(f"RNN入力形状: {rnn_input.shape}")  # 結果: (640, 10)

# 処理後に元の形状に戻す
output = rnn_input  # 何らかの処理
output_reshaped = output.reshape(32, 20, 10)
print(f"処理後の形状: {output_reshaped.shape}")  # 結果: (32, 20, 10)

応用テクニック

複雑な形状変換

import numpy as np

# 6×8の画像を2×2のブロックに分割
image = np.arange(48).reshape(6, 8)
print("元の画像:")
print(image)

# 2×2ブロックに分割(3×4個のブロック)
blocks = image.reshape(3, 2, 4, 2).transpose(0, 2, 1, 3).reshape(12, 2, 2)
print(f"ブロック数: {blocks.shape[0]}")
print("最初のブロック:")
print(blocks[0])

条件付きreshape

import numpy as np

def smart_reshape(arr, target_rows):
    """要素数に応じて柔軟にreshapeする関数"""
    total_elements = arr.size
    
    if total_elements % target_rows != 0:
        # パディングを追加して調整
        padding_needed = target_rows - (total_elements % target_rows)
        arr_padded = np.pad(arr, (0, padding_needed), constant_values=0)
        total_elements = arr_padded.size
    else:
        arr_padded = arr
    
    cols = total_elements // target_rows
    return arr_padded.reshape(target_rows, cols)

# 使用例
data = np.arange(23)  # 23個の要素(素数)
result = smart_reshape(data, 5)
print("柔軟なreshape結果:")
print(result)

まとめ

操作内容コマンド例使う場面
1次元 → 2次元arr.reshape(2, 3)表形式に整理
自動で次元を決めるarr.reshape(3, -1)一方向のサイズが決まっている
1次元化(flatten)arr.reshape(-1)機械学習の前処理
列ベクトル化arr.reshape(-1, 1)数学的な計算
行ベクトル化arr.reshape(1, -1)横一列に表示
転置(行列の入れ替え)arr.T行と列を入れ替え

トラブルシューティング早見表

エラー内容原因解決方法
ValueError: cannot reshape要素数が合わないarr.sizeを確認し、掛け算が合う形状を指定
形状が変わらない代入し忘れarr = arr.reshape(...) で代入
期待した結果にならない転置と混同行列の入れ替えならarr.Tを使用

コメント

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