はじめに
毎回,毎回numpyの連結で悩むことがあるので,一回ちゃんと整理しようと思って自分用メモです
環境
- python3.6.6
- Windows 10
- anaconda
- numpy 1.14.3
悩み
- 連結する方向にいつも悩む
参考
連結
こんな時に連結したい
ロボットの状態をx,y,thで分けて計算してて,そっから統合してstateにしたいとか...
連結で使えるコマンド
- hstack
- vstack
- stack
- concatenate
プログラムと動作の考察
簡単なプログラムです
import numpy as np
class Connect_array():
def __init__(self):
self.a = np.array([[1, 3, 5], [2, 4, 6]])
self.b = np.array([[7, 9, 11], [8, 10, 12]])
def Hstack(self):
print('a = {0}, b = {1}'.format(self.a, self.b))
connected_array = np.hstack((self.a, self.b))
print('hstack(a,b) = {0}'.format(connected_array))
def Vstack(self):
print('a = {0}, b = {1}'.format(self.a, self.b))
connected_array = np.vstack((self.a, self.b))
print('vstack(a,b) = {0}'.format(connected_array))
def Stack(self):
print('axis number ?')
axis_num = int(input())
print('a = {0}, b = {1}'.format(self.a, self.b))
connected_array = np.stack((self.a, self.b), axis=axis_num)
print('stack(a,b) = {0} (axis={1})'.format(connected_array, axis_num))
def Concatenate(self):
print('axis number ?')
axis_num = int(input())
print('a = {0}, b = {1}'.format(self.a, self.b))
connected_array = np.concatenate((self.a, self.b), axis=axis_num)
print('Concatenate(a,b) = {0} (axis={1})'.format(connected_array, axis_num))
def main():
connect_array = Connect_array()
connect_array.Hstack()
connect_array.Vstack()
connect_array.Stack()
connect_array.Concatenate()
if __name__ == '__main__':
main()
hstack
実行結果
# a = [[1, 3, 5], [2, 4, 6]]
# b = [[7, 9, 11], [8, 10, 12]]
# hstack(a,b) = [[1 , 3, 5, 7, 9, 11], [2, 4, 6, 8, 10, 12]]
つまり,axis=1の方向に連結されてます
vstack
# a = [[1, 3, 5], [2, 4, 6]]
# b = [[7, 9, 11], [8, 10, 12]]
# vstack(a,b) = [[1, 3, 5], [2, 4, 6], [7, 9, 11], [8, 10, 12]]
axis=0 方向に連結
stack
stackは特徴的で,次元がふえます!そのまま保持してくっつくイメージですね
ある意味でいちばん,連結っぽいか?
# axis=0
# a = [[1, 3, 5], [2, 4, 6]]
# b = [[7, 9, 11], [8, 10, 12]]
# stack(a,b) = [[[1, 3, 5], [2, 4, 6]], [[7, 9, 11], [8, 10, 12]]]
# axis=1
# a = [[1, 3, 5], [2, 4, 6]]
# b = [[7, 9, 11], [8, 10, 12]]
# stack(a,b) = [[[1, 3, 5], [7, 9, 11]], [[2, 4, 6], [8, 10, 12]]]
concatenate
これは,hstackとかと同じ動きをします
# axis=0
# a = [[1, 3, 5], [2, 4, 6]]
# b = [[7, 9, 11], [8, 10, 12]]
# concatenate(a,b) = [[1, 3, 5], [2, 4, 6], [7, 9, 11], [8, 10, 12]]
# axis = 1
# a = [[1, 3, 5], [2, 4, 6]]
# b = [[7, 9, 11], [8, 10, 12]]
# concotenate(a,b) = [[1 , 3, 5, 7, 9, 11], [2, 4, 6, 8, 10, 12]]
いやaxis=1とはちょっと気になった
軸とか次元とかについていろいろ調べているとでてくるのがこの図
確かにこれはあっていると思います
どっちに連結させるかという行列目線のお話ですね
つまり,例えば,hstackとすれば,axis=1,列方向に連結することができますよ
逆に,vstackとすれば,axis=0,行方向に連結できますよ
ということを表してます
しかし,なにか気持ち悪い
軸に沿っているのだけみると,どう考えても,1次元目の要素に沿っているので,なんか間違っているような気がしてしまうんです
まぁこんな風に横一列に並べて書いたら,
ちょっとよくわからなくなってきましたね笑横並びの図は忘れてください
でもよくよく考えて上図を眺めてたら
確かに成分は1次元目のものを追っているような気がするんですが
軸としては2次元目(axis=1)を示しています
つまり,新たなもの増やしたいなぁっておもったときに,すべての要素にまたがって増やす必要があります
よって,axis=1なんです
逆にaxis=0のときは,何も増やさなくていいですね,というかすべての要素にまたがる必要はありません
よってaxis=0なのか
と理解しました
ただ,違う見方をすれば,すべての要素にかかわってるのがaxis=0という見方もできるかとおもいます
足し算するときみたいなね 下の図みたいに
なので,これはあくまで,僕の考え方です
- 新しいものを増やすときにすべての要素にまたがなくていいもの
- 足し算するときに各々の要素を見る
いけてそうですね
一番おおくまたいでるやつがaxis=0になってます
要素で考えてもいけそうです!
ちなみにこれらの考え方は
sum
とかそういう系の関数にも使えますので!!