Edited at

[Python]Numpyの参照、抽出、結合


1箇所を指定してアクセスする


一次元の場合

X[index]で指定する。最初のデータのindexは0になる。(Matlabの場合は1なので混乱する)

In [1]: import numpy as np

In [2]: X = np.arange(10)

In [3]: print X
[0 1 2 3 4 5 6 7 8 9]

In [4]: print X[0]
0

In [5]: print X[2]
2

最後のデータ数えて指定したいときはX[-index]とする。C言語などのようにX[len(X)-1]としなくてもよい。

最後のデータのIndexは-1となり、最初から指定する時は0からなので若干混乱しがち。

In [6]: print X[-1]

9


二次元の場合

多次元の場合は、カンマ(,)で区切ってそれぞれを指定する。指定の仕方は一次元の時と同じ。

In [17]: X = np.arange(25).reshape(5,5)

In [18]: print X
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]
[20 21 22 23 24]]

In [19]: print X[3,2]
17

In [20]: print X[-1,-2]
23


範囲を指定してアクセスする


一次元の場合

範囲を指定してアクセスする場合は、X[start:end:step]のように指定する。

このときendは含まれないので注意が必要。(Matlabではendは含まれる。)

startを省略すると最初からになり、endを省略すると最後までになり、stepを省略するとstepが1になる。

In [7]: print X[1:3]

[1 2]

In [8]: print X[3:]
[3 4 5 6 7 8 9]

In [9]: print X[:3]
[0 1 2]

In [10]: print X[:]
[0 1 2 3 4 5 6 7 8 9]

In [11]: print X[::]
[0 1 2 3 4 5 6 7 8 9]

In [12]: print X[::2]
[0 2 4 6 8]

start,endにマイナスのIndexを指定してもよい。またstepをマイナスにするとデータが最後から取得される。

In [13]: print X[-3:-1]

[7 8]

In [14]: print X[-3:]
[7 8 9]

In [15]: print X[:-3]
[0 1 2 3 4 5 6]

In [16]: print X[::-1]
[9 8 7 6 5 4 3 2 1 0]


二次元の場合

多次元の場合は、カンマ(,)で区切ってそれぞれを指定する。指定の仕方は一次元の時と同じ。

In [57]: X = np.arange(25).reshape(5,5)

In [58]: print X
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]
[20 21 22 23 24]]

In [59]: print X[1:3,0:2]
[[ 5 6]
[10 11]]

In [60]: print X[1:3,::-1]
[[ 9 8 7 6 5]
[14 13 12 11 10]]


行を抽出する

X[row], X[row,], X[row,:]の3つの方法の結果は同じになる。

ただしX[row,]は後述の列を抽出するときにX[,col]ができないのでおすすめしない。

rowの部分は、1箇所指定でも、範囲指定でもよい。

In [21]: print X[1]

[5 6 7 8 9]

In [22]: print X[1,]
[5 6 7 8 9]

In [23]: print X[1,:]
[5 6 7 8 9]


列を抽出する

X[:,col]で指定した列が取り出せるが、取り出した結果は下記の通り1次元のnumpy arrayになる。

Matlabだと同様に列を抽出すると列ベクトルになるのでそのまま行列演算に使えるが、

numpyの場合は抽出した結果が1次元のnumpy arrayになるので、この結果を行列演算に使うときは注意が必要。

In [24]: print X[:,1]

[ 1 6 11 16 21]


条件を満たすデータを取り出す

X < 3とすると条件を満たす箇所がTrue,満たさない箇所がFalseとなるnumpy arrayが返される。


In [1]: import numpy as np

In [2]: X = np.arange(24,-1,-1).reshape(5,5)

In [3]: print X
[[24 23 22 21 20]
[19 18 17 16 15]
[14 13 12 11 10]
[ 9 8 7 6 5]
[ 4 3 2 1 0]]

In [4]: X < 3
Out[4]:
array([[False, False, False, False, False],
[False, False, False, False, False],
[False, False, False, False, False],
[False, False, False, False, False],
[False, False, True, True, True]], dtype=bool)

In [5]: X % 2 == 0
Out[5]:
array([[ True, False, True, False, True],
[False, True, False, True, False],
[ True, False, True, False, True],
[False, True, False, True, False],
[ True, False, True, False, True]], dtype=bool)

X[X<3]X[X%2==0]とすると、条件を満たす箇所の値が返される。

In [6]: X[X<3]

Out[6]: array([2, 1, 0])

In [7]: X[X%2==0]
Out[7]: array([24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2, 0])


条件を満たすデータを書き換える

X[X%2==0]=0とすると、Trueの箇所だけが書き換えられる。

In [8]: X[X%2==0]=0

In [9]: print X
[[ 0 23 0 21 0]
[19 0 17 0 15]
[ 0 13 0 11 0]
[ 9 0 7 0 5]
[ 0 3 0 1 0]]

[]の中は式でなくても、書き換える場所がTrueになっているnumpy arrayであればよい。

In [10]: X = np.arange(24,-1,-1).reshape(5,5)

In [11]: cond = X%2==0

In [12]: print cond
[[ True False True False True]
[False True False True False]
[ True False True False True]
[False True False True False]
[ True False True False True]]

In [13]: X[cond]=0

In [14]: print X
[[ 0 23 0 21 0]
[19 0 17 0 15]
[ 0 13 0 11 0]
[ 9 0 7 0 5]
[ 0 3 0 1 0]]


指定した行、列の値を取り出す。


行を指定する場合

In [34]: X = np.arange(24,-1,-1).reshape(5,5)

In [35]: print X
[[24 23 22 21 20]
[19 18 17 16 15]
[14 13 12 11 10]
[ 9 8 7 6 5]
[ 4 3 2 1 0]]

In [36]: X[[1,3],:]
Out[36]:
array([[19, 18, 17, 16, 15],
[ 9, 8, 7, 6, 5]])


列を指定する場合

In [37]: X[:,[0,2]]

Out[37]:
array([[24, 22],
[19, 17],
[14, 12],
[ 9, 7],
[ 4, 2]])

行を指定する場合と列を指定する場合を合わせると下記のようになる。

これは1行0列目と3行2列目のデータが取り出されている。

In [38]: X[[1,3],[0,2]]

Out[38]: array([19, 7])

1行目か3行目でかつ0列目、2列目のデータを取り出す場合下記のようにnp.ix_を使う。

np.ix_では行番号と列番号が入ったnumpy arrayのtupleが返される。

In [39]: X[np.ix_([1,3],[0,2])]

Out[39]:
array([[19, 17],
[ 9, 7]])

In [40]: np.ix_([1,3],[1,2])
Out[40]:
(array([[1],
[3]]), array([[1, 2]]))


0以外の場所を抽出する

Matlabなんかだとfindを使うが、numpyの場合はnonzero()を使用する。または、np.whereでも良い。

In [44]: X = np.arange(24,-1,-1).reshape(5,5)

In [45]: i,j=X.nonzero()

In [46]: print i
[0 0 0 0 0 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4 4 4]

In [47]: print j
[0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3]

In [48]: X[i,j]
Out[48]:
array([24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8,
7, 6, 5, 4, 3, 2, 1])

In [51]: i,j=np.where(X!=0)

In [52]: print i
[0 0 0 0 0 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4 4 4]

In [53]: print j
[0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3]

In [54]: X[i,j]
Out[54]:
array([24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8,
7, 6, 5, 4, 3, 2, 1])


numpy arrayを結合する。


縦に結合する

vstackを使う

In [76]: X = np.arange(5)

In [77]: Y = np.arange(4,-1,-1)

In [78]: print X
[0 1 2 3 4]

In [79]: print Y
[4 3 2 1 0]

In [80]: np.vstack((X,Y))
Out[80]:
array([[0, 1, 2, 3, 4],
[4, 3, 2, 1, 0]])


横に結合する

hstackを使う

In [81]: np.hstack((X,Y))

Out[81]: array([0, 1, 2, 3, 4, 4, 3, 2, 1, 0])

X,Yを列ベクトルにして横に結合する場合は下記のようになる。

In [82]: X.reshape(len(X),1)

Out[82]:
array([[0],
[1],
[2],
[3],
[4]])

In [83]: Y.reshape(len(Y),1)
Out[83]:
array([[4],
[3],
[2],
[1],
[0]])

In [84]: np.hstack((X.reshape(len(X),1),Y.reshape(len(Y),1)))
Out[84]:
array([[0, 4],
[1, 3],
[2, 2],
[3, 1],
[4, 0]])


一次元numpy arrayのtransposeの注意点

X.transposeでも良さそうだが、一次元のnumpy arrayをtransposeしても何も起きない。

二次元にしてからtransposeすると列ベクトルにできる。

transposeは転置の意味。

In [87]: X.transpose()

Out[87]: array([0, 1, 2, 3, 4])

In [88]: X.reshape(1,len(X))
Out[88]: array([[0, 1, 2, 3, 4]])

In [89]: X.reshape(1,len(X)).transpose()
Out[89]:
array([[0],
[1],
[2],
[3],
[4]])


画像の結合

行列を結合は画像をくっつけたりするのにも使える。


ipython

In [102]: from skimage import data

In [103]: from skimage import io

In [104]: image = data.lena()

In [105]: image.shape
Out[105]: (512, 512, 3)

In [106]: patch1 = image[200:200+32,200:200+32,:]

In [107]: patch2 = image[300:300+32,300:300+32,:]

In [108]: patch12 = np.hstack((patch1,patch2))


image

20160104_1.png

patch1

20160104_2.png

patch2

20160104_3.png

patch12

20160104_4.png