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_1
とvec_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で次元を変えてあげるのが吉.
##参考サイト様