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

  • 114
    Like
  • 0
    Comment
More than 1 year has passed since last update.

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

一次元の場合

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

ipython
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からなので若干混乱しがち。

ipython
In [6]: print X[-1]
9

二次元の場合

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

ipython
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になる。

ipython
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をマイナスにするとデータが最後から取得される。

ipython
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]

二次元の場合

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

ipython
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箇所指定でも、範囲指定でもよい。

ipython
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になるので、この結果を行列演算に使うときは注意が必要。

ipython
In [24]: print X[:,1]
[ 1  6 11 16 21]

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

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

ipython

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]とすると、条件を満たす箇所の値が返される。

ipython
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の箇所だけが書き換えられる。

ipython
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であればよい。

ipython
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]]

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

行を指定する場合

ipython
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]])

列を指定する場合

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

行を指定する場合と列を指定する場合を合わせると下記のようになる。
これは1行0列目と3行2列目のデータが取り出されている。

ipython
In [38]: X[[1,3],[0,2]]
Out[38]: array([19,  7])

1行目か3行目でかつ0列目、2列目のデータを取り出す場合下記のようにnp.ix_を使う。
np.ix_では行番号と列番号が入ったnumpy arrayのtupleが返される。

ipython
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でも良い。

ipython
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])
ipython
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を使う

ipython
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を使う

ipython
In [81]: np.hstack((X,Y))
Out[81]: array([0, 1, 2, 3, 4, 4, 3, 2, 1, 0])

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

ipython
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は転置の意味。

ipython
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