【Numpy】.shapeで得られる値の理解


本記事は

会社である研修を受けた際の教材のshapeで得られる結果の解説 が不親切だった にもう少し説明が欲しかったので、自分の理解のために整理します。
いろんなサイトで見ても、例とする配列に入っている数字が1~12の連番かつ、reshapeで指定する数値が2とか3なので、何を指定しているのか混乱してしまいます。(私だけ?)

Numpyの.shapeコマンド

配列の各次元の要素数を返します。
簡単に言えば、配列の行数、列数、奥行き数を返してくれるもの。
「奥行き数」と言うのが正しい呼称かはわかりませんが、私のイメージです。

Numpyはインポートして使います。
よくnpとしてインポートして使います。

import numpy as np

実際にどんな結果が得られるか確認してみる

(個人的に)わかりやすくするためにランダムな値が入った配列を作ります。
.random.randint()で整数の乱数を発生させます。
ちなみに(開始値, 終了値, 要素数)の順で、開始値から終了値までの範囲で要素数の数だけ乱数を得るという、指定方法です。

x = np.random.randint(10, 50, 24)
print(x)

結果は以下。
ランダムな24個の要素が入った配列を得ました。

[29 39 42 12 45 44 21 45 32 16 45 38 23 17 29 20 26 47 38 10 22 28 29 44]

単純なshapeを使ってみる

まずは単純にshapeの結果を見ます。

print(x.shape)

結果は以下
一次元の要素が24あるということがわかります。

(24,)

reshapeで2次元の配列にしてみる

reshapeで形状を変換して確認してみます。

a = x.reshape(6, 4)
print(a)
print(a.shape)

結果は以下。
6行、4列の行列になりました。

[[29 39 42 12]
 [45 44 21 45]
 [32 16 45 38]
 [23 17 29 20]
 [26 47 38 10]
 [22 28 29 44]]
(6, 4)

reshapeで3次元の配列にしてみる

同じくreshapeで3次元に変換して確認してみます。
ここで重要なのは、奥行き数を一番初めに指定すること。
.reshape(奥行き数, 行数, 列数)です。
不親切な教材にはここの解説がなかったので、何を指定している理解が難しかった。
あと、どのサイトや教材も要素の数が2,3とかで、なんの値を指定しているかがわかりにくい。もっと極端な値にすればわかりやすいのでは?

b = x.reshape(2, 3, 4)
print(b)
print(b.shape)

結果は以下。
printで行列を表示すると、奥行きが別の行列が改行されて表示されますね。
shapeで得られる結果では、奥行き数が一番頭に来ています。

[[[29 39 42 12]
  [45 44 21 45]
  [32 16 45 38]]

 [[23 17 29 20]
  [26 47 38 10]
  [22 28 29 44]]]
(2, 3, 4)

いろんな解説はもっと極端にしたらどうですか?

極端に奥行き数を6に変更して確認してみます。

c = x.reshape(12, 1, 2)
print(c)
print(c.shape)

結果は以下。
1行×2列の行列が12個表示されますね。
これでreshapeで指定する順番が理解できました。
shapeで得られる結果の順番も同様です。

[[[29 39]]

 [[42 12]]

 [[45 44]]

 [[21 45]]

 [[32 16]]

 [[45 38]]

 [[23 17]]

 [[29 20]]

 [[26 47]]

 [[38 10]]

 [[22 28]]

 [[29 44]]]
(12, 1, 2)

終わりに

本記事は個人の理解のための整理です。
色々勉強していると、こんな例題で本当に教える気があるのか?という教材も見かけます。
(私の理解力が足りないだけかもしれませんが)初学者は極端な例を使うことで理解が進む、というのはあるあるだと思います。
今後もこのように理解しにくかったこと、気になったことを整理したいと思います。
どなたかのお役に立てれば幸いです。