NumPyの`resize`の使い方 – 配列の形状を変更する(要素の追加・削除あり)

NumPyは、Python数値計算を効率的に行うためのライブラリです。配列の形状を操作する機能が豊富に用意されています。この記事では、配列の形状を変更する関数の一つであるresizeの基本的な使い方について解説します。reshapeとは異なり、resizeは配列の要素数を変更できる点が特徴です。

numpy.resizendarray.resize の違い

resizeには、numpy.resize()という関数と、NumPy配列オブジェクトのメソッドであるndarray.resize()の2種類が存在します。両者は似ていますが、動作に重要な違いがあります。

機能 numpy.resize (関数) ndarray.resize (メソッド)
操作対象 元の配列は変更せず、新しい配列を返す 元の配列を直接変更する (in-place)
戻り値 新しい形状の配列 None
要素追加時の値 元の配列の要素を繰り返して埋める 0で埋める
他からの参照 影響なし 他の変数から参照されている場合、エラーが発生することがある

一般的に、元のデータを保持したまま新しい形状の配列を得たい場合はnumpy.resize()を、元の配列そのものを変更したい場合はndarray.resize()を使用します。

numpy.resize の基本的な使い方

numpy.resize(a, new_shape)は、指定した配列anew_shapeで指定した形状に変更した新しい配列を返します。

配列を大きくする場合(要素の追加)

新しい形状が元の配列より大きい場合、元の配列の要素が繰り返されて新しい要素が埋められます。

import numpy as np

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

# 配列aを(2, 3)の形状に変更
b = np.resize(a, (2, 3))

print(b)

出力

[[1 2 3]
 [1 2 3]]

この例では、bの2行目の要素が、aの要素[1, 2, 3]の繰り返しで埋められています。

配列を小さくする場合(要素の削除)

新しい形状が元の配列より小さい場合、末尾の要素が切り捨てられます。

import numpy as np

a = np.array([[1, 2, 3], [4, 5, 6]])

# 配列aを要素数3の1次元配列に変更
b = np.resize(a, 3)

print(b)

出力

[1 2 3]

ndarray.resize の基本的な使い方

a.resize(new_shape)は、配列aそのものの形状を変更します。戻り値はない(None)ため、新しい変数に代入する使い方をしません。

配列を大きくする場合(要素の追加)

新しい形状が元の配列より大きい場合、新しい要素は0で埋められます。これはnumpy.resizeの挙動と異なる点です。

import numpy as np

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

# 配列a自体の形状を(2, 3)に変更
a.resize((2, 3))

print(a)

出力

[[1 2 3]
 [0 0 0]]

2行目の要素が0で埋められていることがわかります。

配列を小さくする場合(要素の削除)

新しい形状が元の配列より小さい場合、numpy.resizeと同様に末尾の要素が切り捨てられます。

import numpy as np

a = np.array([[1, 2, 3], [4, 5, 6]])

# 配列a自体の形状を要素数4の1次元配列に変更
a.resize(4)

print(a)

出力

[1 2 3 4]

ndarray.resize の注意点

ndarray.resizeは、他の変数から参照されていない場合にのみ使用できます。もし他の変数が同じ配列を参照している場合、ValueErrorが発生します。

import numpy as np

a = np.array([1, 2, 3, 4, 5, 6])

# bがaを参照している
b = a

# aの形状を変更しようとするとエラーが発生する
# a.resize((2, 3))
# ValueError: cannot resize an array that has been referenced...

このチェックは、意図しない副作用を防ぐためのものです。どうしてもリサイズしたい場合は、引数refcheck=Falseを指定することで強制的に実行できますが、推奨されません。

resizereshape の違い

resizeと似た機能を持つ関数にreshapeがありますが、その役割は明確に異なります。

機能 resize reshape
素数の変更 可能 不可能
用途 要素の追加・削除を伴う形状変更 素数を変えずに形状のみ変更

reshapeは、元の配列の要素数を維持したまま、形状(次元や各次元の要素数)を変更します。そのため、変更前と変更後で要素数が一致している必要があります。

import numpy as np

a = np.arange(6) # array([0, 1, 2, 3, 4, 5])

# reshapeは要素数が同じ範囲でのみ可能
b = a.reshape((2, 3))
print(b)
# [[0 1 2]
#  [3 4 5]]

# 要素数が異なる形状へのreshapeはエラーになる
# a.reshape((3, 3))
# ValueError: cannot reshape array of size 6 into shape (3,3)

# resizeは要素数が異なっても動作する
c = np.resize(a, (3, 3))
print(c)
# [[0 1 2]
#  [3 4 5]
#  [0 1 2]]

まとめ

numpy.resizeは、配列の要素数を変更して形状を再定義するための関数です。

  • 新しい配列として結果を得たい場合はnumpy.resize()を使用します。要素が不足する場合は元の配列の要素が繰り返されます。
  • 元の配列を直接変更したい場合はndarray.resize()を使用します。要素が不足する場合は0で埋められます。
  • 素数を変えずに形状だけを変更したい場合はreshape()を使用します。

これらの関数の違いを理解し、目的に応じて適切に使い分けることで、データ処理をより柔軟に行うことができます。