NumPy配列ndarrayの形状を変換するreshapeの使い方と-1の意味

NumPy配列ndarrayの形状を変換するにはndarrayのreshape()メソッドかnumpy.reshape()関数を使います。

numpy.ndarray.reshape — NumPy v1.15 Manual numpy.reshape — NumPy v1.15 Manual

ここでは以下の内容について説明します。

ndarray.reshape()メソッドの使い方 numpy.reshape()関数の使い方 変換順序を指定: 引数order -1による形状の指定 reahape()が返すのはビュー

NumPy配列ndarrayの形状や次元数などを確認したい場合は以下の記事を参照。

形状変換によってサイズが1の新たな次元を追加する場合はreshape()ではなくnumpy.newaxisを使う方法もあります。

また、NumPy配列ndarray同士の二項演算(四則演算など)では自動的に形状が揃えられてから計算されるブロードキャストという仕組みがあります。

ndarray.reshape()メソッドの使い方

以下の一次元のNumPy配列ndarrayを例とします。

import numpy as np

a = np.arange(24)

print(a)
# [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]

print(a.shape)
# (24,)

print(a.ndim)
# 1

numppy.ndarrayのreshape()メソッドの第一引数に変換後の形状をリストやタプルで指定します。

a_4_6 = a.reshape([4, 6])

print(a_4_6)
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]
#  [12 13 14 15 16 17]
#  [18 19 20 21 22 23]]

print(a_4_6.shape)
# (4, 6)

print(a_4_6.ndim)
# 2

a_2_3_4 = a.reshape([2, 3, 4])

print(a_2_3_4)
# [[[ 0  1  2  3]
#   [ 4  5  6  7]
#   [ 8  9 10 11]]
#
#  [[12 13 14 15]
#   [16 17 18 19]
#   [20 21 22 23]]]

print(a_2_3_4.shape)
# (2, 3, 4)

print(a_2_3_4.ndim)
# 3

元の配列と要素数が一致する形状でないとエラーValueErrorとなります。

# a_5_6 = a.reshape([5, 6])
# ValueError: cannot reshape array of size 24 into shape (5,6)

リストやタプルではなく、各次元の値を順に指定しても問題ありません。

print(a.reshape(4, 6))
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]
#  [12 13 14 15 16 17]
#  [18 19 20 21 22 23]]

print(a.reshape(2, 3, 4))
# [[[ 0  1  2  3]
#   [ 4  5  6  7]
#   [ 8  9 10 11]]
#
#  [[12 13 14 15]
#   [16 17 18 19]
#   [20 21 22 23]]]

numpy.reshape()関数の使い方

numpy.reshape()関数では、第一引数に元のnumpy.ndarray、第二引数に変換したい形状をリストやタプルで指定します。元の配列と要素数が一致する形状でないとエラーValueErrorとなります。

print(np.reshape(a, [4, 6]))
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]
#  [12 13 14 15 16 17]
#  [18 19 20 21 22 23]]

print(np.reshape(a, [2, 3, 4]))
# [[[ 0  1  2  3]
#   [ 4  5  6  7]
#   [ 8  9 10 11]]
#
#  [[12 13 14 15]
#   [16 17 18 19]
#   [20 21 22 23]]]

# print(np.reshape(a, [5, 6]))
# ValueError: cannot reshape array of size 24 into shape (5,6)

numpy.reshape()関数の第二引数には必ずリストやタプルを指定します。numppy.ndarrayのreshape()メソッドのように各次元の値を順に指定するとエラーValueErrorとなります。

print(a.reshape(4, 6))
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]
#  [12 13 14 15 16 17]
#  [18 19 20 21 22 23]]

# print(np.reshape(a, 4, 6))
# ValueError: cannot reshape array of size 24 into shape (4,)

変換順序を指定: 引数order

変換順序を引数orderで指定します。order='C'がC言語方式でorder='F'がFORTRAN方式。デフォルトはorder='C'。 以下のように結果が異なる。

print(a.reshape([4, 6], order='C'))
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]
#  [12 13 14 15 16 17]
#  [18 19 20 21 22 23]]

print(a.reshape([4, 6], order='F'))
# [[ 0  4  8 12 16 20]
#  [ 1  5  9 13 17 21]
#  [ 2  6 10 14 18 22]
#  [ 3  7 11 15 19 23]]

print(a.reshape([2, 3, 4], order='C'))
# [[[ 0  1  2  3]
#   [ 4  5  6  7]
#   [ 8  9 10 11]]
#
#  [[12 13 14 15]
#   [16 17 18 19]
#   [20 21 22 23]]]

print(a.reshape([2, 3, 4], order='F'))
# [[[ 0  6 12 18]
#   [ 2  8 14 20]
#   [ 4 10 16 22]]
#
#  [[ 1  7 13 19]
#   [ 3  9 15 21]
#   [ 5 11 17 23]]]

numpy.reshape()関数でも同様に指定可能。

print(np.reshape(a, [4, 6], order='F'))
# [[ 0  4  8 12 16 20]
#  [ 1  5  9 13 17 21]
#  [ 2  6 10 14 18 22]
#  [ 3  7 11 15 19 23]]

numppy.ndarrayのreshape()メソッドは上述のように形状を各次元の値を順に指定することを許可しているので、引数orderを指定する場合はキーワードを明示しないとエラーTypeErrorとなります。 numpy.reshape()関数では第三引数がorderとなるのでキーワードは省略可。

# print(a.reshape([4, 6], 'F'))
# TypeError: 'list' object cannot be interpreted as an integer

print(np.reshape(a, [4, 6], 'F'))
# [[ 0  4  8 12 16 20]
#  [ 1  5  9 13 17 21]
#  [ 2  6 10 14 18 22]
#  [ 3  7 11 15 19 23]]

-1による形状の指定

形状の指定では-1を使うことができます。 以下、numppy.ndarrayのreshape()メソッドを例とするがnumpy.reshape()関数でも同様。 -1とした次元の長さは他の次元の指定値から推測されて自動的に決定される。サイズの大きい配列の形状を変換するときに便利。

print(a.reshape([4, -1]))
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]
#  [12 13 14 15 16 17]
#  [18 19 20 21 22 23]]

print(a.reshape([2, -1, 4]))
# [[[ 0  1  2  3]
#   [ 4  5  6  7]
#   [ 8  9 10 11]]
#
#  [[12 13 14 15]
#   [16 17 18 19]
#   [20 21 22 23]]]

-1を指定できるのは一つの次元に対してのみ。二つ以上の次元に指定するとエラーValueError。

# print(a.reshape([2, -1, -1]))
# ValueError: can only specify one unknown dimension

また、条件を満たす値が存在しない場合もエラーValueErrorとなります。

# print(a.reshape([2, -1, 5]))
# ValueError: cannot reshape array of size 24 into shape (2,newaxis,5)

reahape()が返すのはビュー

numppy.ndarrayのreshape()メソッドもnumpy.reshape()関数もコピーではなくビュー(参照)を返すので注意。 以下、numppy.ndarrayのreshape()メソッドを例とするがnumpy.reshape()関数でも同様。 以下のように、元のオブジェクトを変更するとreshape()メソッドが返したビューオブジェクトも変更される。

a_4_6 = a.reshape([4, 6])
print(a_4_6)
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]
#  [12 13 14 15 16 17]
#  [18 19 20 21 22 23]]

a[0] = 100
print(a)
# [100   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17
#   18  19  20  21  22  23]

print(a_4_6)
# [[100   1   2   3   4   5]
#  [  6   7   8   9  10  11]
#  [ 12  13  14  15  16  17]
#  [ 18  19  20  21  22  23]]

逆の場合も同様。reshape()メソッドが返したビューオブジェクトを変更すると元のオブジェクトも変更される。

a_4_6[0, 0] = 0
print(a_4_6)
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]
#  [12 13 14 15 16 17]
#  [18 19 20 21 22 23]]

print(a)
# [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]

コピーを取得したい場合はcopy()メソッドを使います。この場合、それぞれのオブジェクトに変更を加えても他方のオブジェクトは影響されない。

a_4_6_copy = a.reshape([4, 6]).copy()

print(a_4_6_copy)
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]
#  [12 13 14 15 16 17]
#  [18 19 20 21 22 23]]

a[0] = 100
print(a)
# [100   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17
#   18  19  20  21  22  23]

print(a_4_6_copy)
# [[ 0  1  2  3  4  5]
#  [ 6  7  8  9 10 11]
#  [12 13 14 15 16 17]
#  [18 19 20 21 22 23]]

a_4_6_copy[0, 0] = 200
print(a_4_6_copy)
# [[200   1   2   3   4   5]
#  [  6   7   8   9  10  11]
#  [ 12  13  14  15  16  17]
#  [ 18  19  20  21  22  23]]

print(a)
# [100   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17
#   18  19  20  21  22  23]

シェア

関連カテゴリー

Python NumPy

NumPyで条件に応じた処理を行うwhereの使い方 NumPyのブロードキャスト(形状の自動変換) NumPy配列ndarrayをprint表示で省略するかしないか設定 NumPy配列ndarrayをシフト(スクロール)させるnp.roll NumPyのデータ型dtype一覧とastypeによる変換(キャスト) NumPy配列ndarrayの条件を満たす要素数をカウント NumPyでRGB画像の色チャンネルを分離して単色化、白黒化、色交換 Python, NumPyでグラデーション画像を生成 Pythonのリストと配列とnumpy.ndarrayの違いと使い分け pandas.DataFrame, SeriesとNumPy配列ndarrayを相互に変換 NumPyの配列ndarrayの欠損値np.nanを含む行や列を削除 Pythonでの画像処理、Pillow, NumPy, OpenCVの違いと使い分け NumPy配列の行・列ごとの合計、平均、最大、最小などを算出 NumPyで任意の行・列を削除するdeleteの使い方 Python, NumPyで画像処理(読み込み、演算、保存)

Last Updated: 6/26/2019, 10:34:03 PM