Python
numpy
python3

Pythonのnumpyの配列でつまづいた時の対処法

Python の numpy の配列でつまづいた

ある事情で, numpyを使ったのだけれどそこでnumpy式配列(np.array)を操作する上で
色々つまづいたので備忘録も兼ねて残しておく.

numpyで配列を用意

今回は配列と言うか行列が欲しいので以下のように今回は配列を複数用意

import numpy as np
matrix_1 = np.zeros(m, n)
vec_1 = np.zeros(m, 1)
matrix_2 = np.zeros(m, n)

このように適当に0行列を作成(m, nには任意の自然数を入れてください).
これをあーだこーだ計算して, とりあえずmatarix_1vec_1に値が入っているとします.

色々操作する

計算も終わり、さてmatrix_2に値を入れていく.
今回は, 縦ベクトルで各列を置換していきたい.なので, とりあえずコードを書く.

vec = matrix[:, i] * vec_1 # これは要素同士の掛け算になる
matrix_2[:, i] = vec

iは0<i<nです.
これでいいだろうと, 実際に動かすと
エラーを吐く.
主にmatrix_2[:, i] = vecの部分で次元が違うとかでエラーを吐く.

何で?

要素同士で, かつ縦ベクトル同士の掛け算では?ってなりそうなのだけれども実際のところこれは,
サイズ3の横型配列と(3,1)のベクトルの計算に当たる.
つまりvec = matrix[:, i] * vec_1の結果は(m, m)の行列が返ってくることになる.
だからエラーを吐く. なので以下のようにしてあげると吉.

vec = matrix[:, i].reshape(-1, 1) * vec_1

こうするとスライスした部分を縦ベクトルに変換してくれる.
ちなみに, numpyのreshapeに-1を引数として渡すと勝手に残りの引数からサイズを計算してくれる. 便利.

続き

とりあえず, 上のエラーも直したのだから実行し直そうとすると
またもやエラーを吐く.
同様に次元がウンタラカンタラで.

何で?(2回目)

これはスライスした場合の結果の値の問題で, スライスした値を何かの変数に代入しようとしたり, 計算に使おうとすると横型配列になる. これは上の事例を見てもらえばわかる通り.
では, 置換しようとしてmatrix_2[:, i]のように指定すると, どうなるか.
結果は縦型の配列として扱うことになる.
色々面倒だけど, 実際にこうなる.つまり, matrix_2[:, i] = vecというのは, サイズmの配列(1次元)に対し, サイズ(m, 1)の縦ベクトル(2次元)を代入しようとしているのでエラーを吐いている.見た目は同じ1次元なのだけれどもね.
ということで, 修正する.

vec_r = vec.reshape(m)
matrix_2[:, i] = vec_r

こうすると, 無事エラーを吐かずに, 計算が終わる.

まとめ

配列、もしくは行列のスライスの結果は1次元の配列として返ってくる.
なので、縦ベクトルにしたり縦ベクトルで置換したい場合はreshapeで次元を変えてあげるのが吉.

参考サイト様