numpy – reshape、expand_dims、squeeze など形状を変更する関数の使い方

目次

概要

NumPy の配列の形状を変更する関数について解説します。

numpy.reshape

配列のデータを変更せずに配列に新しい形を与えます。

numpy.reshape(a, newshape, order="C")
引数
名前 デフォルト値
a array_like
形状を変更する配列。
newshape int, tuple of ints
新しい形状は、元の形状と要素数が一致していなければなりません。整数の場合は、その長さの1次元配列となります。1つの形状の次元が -1 になることもありますが、この場合は配列の長さと残りの次元から値が推測されます。
order {“C”, “F”, “A”} “C”
形状を変更する際に値を読み込み、新しい配列に配置する順番。
返り値
名前 説明
reshaped_array 可能な場合はビューとなり、そうでない場合はコピーとなります。

numpy.reshape() は配列の要素数を変更せずに配列の形状を変更します。

In [1]:
import numpy as np

a = np.arange(12)

b = np.reshape(a, (3, 4))
print(b)
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]

配列の要素数が変わるような形状の変更はできないことに注意してください。 以下は (12,) の配列の形状を (5, 5) に変更しようとしていますが、変更前の要素数は 12、変更後の要素数は 5×5=25 となり、要素数が変わってしまうので、以下のようなエラーが表示されます。

ValueError: cannot reshape array of size <要素数> into shape <変更後の形状>

In [2]:
a = np.arange(12)
b = np.reshape(a, (5, 5))
# ValueError: cannot reshape array of size 12 into shape (5,5)
ValueErrorTraceback (most recent call last) <ipython-input-2-f43465587cf0> in <module> 1 a = np.arange(12) —-> 2 b = np.reshape(a, (5, 5)) 3 # ValueError: cannot reshape array of size 12 into shape (5,5) <__array_function__ internals> in reshape(*args, **kwargs) ~/.pyenv/versions/3.8.3/lib/python3.8/site-packages/numpy/core/fromnumeric.py in reshape(a, newshape, order) 299 [5, 6]]) 300 “”” –> 301 return _wrapfunc(a, ‘reshape’, newshape, order=order) 302 303 ~/.pyenv/versions/3.8.3/lib/python3.8/site-packages/numpy/core/fromnumeric.py in _wrapfunc(obj, method, *args, **kwds) 59 60 try: —> 61 return bound(*args, **kwds) 62 except TypeError: 63 # A TypeError occurs if the object does have such a method in its ValueError: cannot reshape array of size 12 into shape (5,5)

order は形状を変更する際に、元の配列から値を読み込み、新しい形状の配列に値を設定する順番を指定できます。

  • "C": 行優先順。
  • "F": 列優先順。

行優先順

列優先順

In [ ]:
a = np.arange(16).reshape(4, 4)
print(a)

print(a.reshape(2, 8, order="C"))
print(a.reshape(2, 8, order="F"))

numpy.ravel

連続する平坦化された配列を返します。

numpy.ravel(a, order="C")
引数
名前 デフォルト値
a array_like
入力配列。a の要素は、order で指定された順番で読み込まれ、1次元配列として詰められます。
order {“C”,”F”, “A”, “K”} “C”
形状を変更する際に値を読み込み、新しい配列に配置する順番。
返り値
名前 説明
y y は、a と同じサブタイプの配列で、形状 (a.size,) を持ちます。a が行列の場合、y は1次元の ndarray であることに注意してください。
In [ ]:
a = np.arange(12).reshape(3, 4)
print(a)

b = np.ravel(a)
print(b)

order は形状を変更する際に、元の配列から値を読み込み、1次元配列に値を設定する順番を指定します。

  • "C": 行優先順。
  • "F": 列優先順。

行優先順

列優先順

軸を追加、削除する関数

numpy.reshape() でもできる以下の操作は頻出のため、専用の関数が用意されています。

名前 説明
numpy.squeeze 配列に次元1の軸を削減する。
numpy.expand_dims 配列に次元1の軸を挿入する。
numpy.atleast_1d 配列の次元が1未満の場合はサイズ1の次元を追加し、1次元配列にする。
numpy.atleast_2d 配列の次元が2未満の場合はサイズ1の次元を追加し、2次元配列にする。
numpy.atleast_3d 配列の次元が3未満の場合はサイズ1の次元を追加し、3次元配列にする。

numpy.expand_dims

配列の形状を展開します。

numpy.expand_dims(a, axis)
引数
名前 デフォルト値
a array_like
入力配列。
axis int
展開された軸の中で、新しい軸が配置される位置。
返り値
名前 説明
res 出力配列。次元の数は入力配列の数よりも1大きい。

サイズ1の軸を指定した axis の前に挿入します

numpy.expand()

In [ ]:
a = np.zeros((3, 4))
print(a.shape)

b = np.expand_dims(a, 1)
print(b.shape)

numpy.expand()

In [ ]:
a = np.zeros((3, 4))
print(a.shape)

b = np.expand_dims(a, 0)
print(b.shape)

numpy.expand()

In [ ]:
a = np.zeros((3, 4))
print(a.shape)

b = np.expand_dims(a, 2)
print(b.shape)

b = np.expand_dims(a, -1)
print(b.shape)

numpy.squeeze

配列の形状から一次元のエントリを削除します。

numpy.squeeze(a, axis=None)
引数
名前 デフォルト値
a array_like
入力データ。
axis None int tuple of ints None
バージョン1.7.0の新機能。
返り値
名前 説明

デフォルトではサイズ1の軸はすべて削減されます。

numpy.squeeze()

In [ ]:
a = np.zeros((3, 1, 1, 1))
print(a.shape)

b = np.squeeze(a)
print(b.shape)

削減する軸を axis で指定できます。

numpy.squeeze()

In [ ]:
a = np.zeros((3, 1, 1, 1))
print(a.shape)

b = np.squeeze(a, axis=1)
print(b.shape)

numpy.squeeze()

In [ ]:
a = np.zeros((3, 1, 1, 1))
print(a.shape)

b = np.squeeze(a, axis=(1, 2))
print(b.shape)

numpy.atleast_1d

入力を少なくとも1つの次元を持つ配列に変換します。

numpy.atleast_1d(*arys)
引数
名前 デフォルト値
arys1, arys2, … array_like
1つまたは複数の入力配列。
返り値
名前 説明
ret それぞれが a.ndim >= 1 を持つ配列、または配列のリスト。必要に応じてコピーを行います。

1次元未満の場合は、次元1の軸を挿入して1次元にします。

  • 0次元: ()(1,)
  • 1次元以上: 変更なし
In [ ]:
d0 = np.zeros(())  # 0次元
d1 = np.zeros((3,))  # 1次元
d2 = np.zeros((3, 4))  # 2次元
d3 = np.zeros((3, 4, 5))  # 3次元
d4 = np.zeros((3, 4, 5, 6))  # 4次元

print(d0.shape, np.atleast_1d(d0).shape)
print(d1.shape, np.atleast_1d(d1).shape)
print(d2.shape, np.atleast_1d(d2).shape)
print(d3.shape, np.atleast_1d(d3).shape)
print(d4.shape, np.atleast_1d(d4).shape)

numpy.atleast_2d

入力を、少なくとも2次元の配列として表示します。

numpy.atleast_2d(*arys)
引数
名前 デフォルト値
arys1, arys2, … array_like
1つまたは複数の配列に似たシーケンス。配列ではない入力は、配列に変換されます。既に2次元以上の配列は保存されます。
返り値
名前 説明
res, res2, … 配列、または配列のリストで、それぞれが a.ndim >= 2 となります。可能な限りコピーは避けられ、2つ以上の次元を持つビューが返されます。

形状が2次元未満の場合は、次元1の軸を挿入して2次元にします。

  • 0次元: ()(1, 1)
  • 1次元: (N)(1, N)
  • 2次元以上: 変更なし
In [ ]:
d0 = np.zeros(())  # 0次元
d1 = np.zeros((3,))  # 1次元
d2 = np.zeros((3, 4))  # 2次元
d3 = np.zeros((3, 4, 5))  # 3次元
d4 = np.zeros((3, 4, 5, 6))  # 4次元

print(d0.shape, np.atleast_2d(d0).shape)
print(d1.shape, np.atleast_2d(d1).shape)
print(d2.shape, np.atleast_2d(d2).shape)
print(d3.shape, np.atleast_2d(d3).shape)
print(d4.shape, np.atleast_2d(d4).shape)

numpy.atleast_3d

入力を、少なくとも3次元の配列として表示します。

numpy.atleast_3d(*arys)
引数
名前 デフォルト値
arys1, arys2, … array_like
1つ以上の配列のようなシーケンス。配列ではない入力は、配列に変換されます。既に3次元以上の配列は保存されます。
返り値
名前 説明
res1, res2, … 配列、または配列のリストで、それぞれが a.ndim >= 3 となります。可能な限りコピーは避けられ、3次元以上のビューが返されます。例えば、形状の1次元配列(N,)は、形状のビュー(1, N, 1)になり、形状の2次元配列(M, N)は、形状のビュー(M, N, 1)になります。

形状が3次元未満の場合は、次元1の軸を挿入して3次元にする。

  • 0次元: ()(1, 1, 1)
  • 1次元: (N)(1, N, 1)
  • 2次元: (N, M)(N, M, 1)
  • 3次元以上: 変更なし
In [ ]:
d0 = np.zeros(())  # 0次元
d1 = np.zeros((3,))  # 1次元
d2 = np.zeros((3, 4))  # 2次元
d3 = np.zeros((3, 4, 5))  # 3次元
d4 = np.zeros((3, 4, 5, 6))  # 4次元

print(d0.shape, np.atleast_3d(d0).shape)
print(d1.shape, np.atleast_3d(d1).shape)
print(d2.shape, np.atleast_3d(d2).shape)
print(d3.shape, np.atleast_3d(d3).shape)
print(d4.shape, np.atleast_3d(d4).shape)

軸を操作する

名前 説明
numpy.transpose 軸の順番に入れ替える。
numpy.moveaxis 軸を指定した位置に移動する。
numpy.swapaxes 2つの軸を入れ替える。

numpy.transpose

配列の次元を入れ替えます。

numpy.transpose(a, axes=None)
引数
名前 デフォルト値
a array_like
入力は配列。
axes list of ints None
デフォルトでは、次元を反転させ、それ以外の場合は与えられた値に従って軸をパーミュートします。
返り値
名前 説明
p a の軸をパームートしたもの。可能な限り、ビューが返されます。

axes を指定しない場合は、元の軸を反転させる。

numpy.transpose()

In [ ]:
a = np.zeros((3, 4, 5))
print(a.shape)  # (3, 4, 5)

b = np.transpose(a)
print(b.shape)  # (5, 4, 3)
In [ ]:
axes を指定した場合は、元の軸を指定した位置に移動する。

![numpy.transpose()](transpose-2.svg)
In [ ]:
a = np.zeros((3, 4, 5))
print(a.shape)  # (3, 4, 5)

b = np.transpose(a, axes=(1, 0, 2))
print(b.shape)  # (4, 3, 5)

numpy.moveaxis

配列の軸を新しい位置に移動します。

numpy.moveaxis(a, source, destination)
引数
名前 デフォルト値
a np.ndarray
軸が並べ替えられるべき配列。
source int, sequence of int
移動する軸の元の位置。これらは一意である必要があります。
destination int, sequence of int
元の軸のそれぞれの移動先の位置。これらも一意である必要があります。
返り値
名前 説明
result 移動された軸を持つ配列。この配列は入力配列のビューです。

軸の位置を source から destination に移動する。

numpy.moveaxis()

In [3]:
a = np.zeros((3, 4, 5))
print(a.shape)  # (3, 4, 5)

b = np.moveaxis(a, 0, 1)
print(b.shape)  # (3, 5, 4)
(3, 4, 5)
(4, 3, 5)

numpy.moveaxis()

In [4]:
a = np.zeros((3, 4, 5))
print(a.shape)  # (3, 4, 5)

b = np.moveaxis(a, 0, 2)
print(b.shape)  # (3, 5, 4)

b = np.moveaxis(a, 0, -1)
print(b.shape)  # (3, 5, 4)
(3, 4, 5)
(4, 5, 3)

numpy.moveaxis()

In [5]:
a = np.zeros((3, 4, 5))
print(a.shape)  # (3, 4, 5)

b = np.moveaxis(a, 2, 0)
print(b.shape)  # (3, 5, 4)
(3, 4, 5)
(5, 3, 4)

numpy.swapaxes

配列の2つの軸を入れ替えます。

numpy.swapaxes(a, axis1, axis2)
引数
名前 デフォルト値
a array_like
入力配列。
axis1 int
1つ目の軸。
axis2 int
2軸目。
返り値
名前 説明
a_swapped NumPy >= 1.10.0では、a がndarrayの場合、a のビューが返され、そうでない場合は新しい配列が作成されます。以前のNumPyのバージョンでは、軸の順序が変更された場合のみ、a のビューが返され、そうでない場合は入力配列が返されます。

2つの軸 axis1 と axis2 を入れ替える。

numpy.swapaxis()

In [6]:
a = np.zeros((3, 4, 5))
print(a.shape)  # (3, 4, 5)

b = np.swapaxes(a, 1, 0)
print(b.shape)  # (4, 3, 5)
(3, 4, 5)
(4, 3, 5)

コメント

コメントする

目次