Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした