LoginSignup
74
81

More than 5 years have passed since last update.

[Python]Numpyデータの並べ替え

Last updated at Posted at 2016-03-09

Sort

numpy.sort(a, axis=-1, kind='quicksort', order=None)

1次元の場合

sortを使うと昇順に並ぶ。降順にしたい場合は、下記のように[::-1]を使うといい

In [3]: x = np.random.randint(0, 100, size=10)

In [4]: print x
[63 82 80 93 65 96 97 75  2 61]

In [5]: print np.sort(x)
[ 2 61 63 65 75 80 82 93 96 97]

In [6]: print np.sort(x)[::-1]
[97 96 93 82 80 75 65 63 61  2]

多次元の場合

多次元の場合は、どの軸のデータをsortするか指定する。省略した場合は、一番最後の軸になる。

In [7]: x = np.random.randint(0, 100, size=(2,10))

In [8]: print x
[[43 70 88 99  0 83 51 17 19 58]
 [11 89 94 11  8 28  9 54 74 67]]

In [9]: print np.sort(x)
[[ 0 17 19 43 51 58 70 83 88 99]
 [ 8  9 11 11 28 54 67 74 89 94]]

In [10]: print np.sort(x,axis=0)
[[11 70 88 11  0 28  9 17 19 58]
 [43 89 94 99  8 83 51 54 74 67]]

降順にしたい場合は、1次元同様[::-1]を使うといい。

In [11]: print x
[[43 70 88 99  0 83 51 17 19 58]
 [11 89 94 11  8 28  9 54 74 67]]

In [12]: print np.sort(x)[:,::-1]
[[99 88 83 70 58 51 43 19 17  0]
 [94 89 74 67 54 28 11 11  9  8]]

In [13]: print np.sort(x,axis=0)[::-1]
[[43 89 94 99  8 83 51 54 74 67]
 [11 70 88 11  0 28  9 17 19 58]]

argsort

numpy.argsort(a, axis=-1, kind='quicksort', order=None)
実際のデータを並べ替えたくない時は、argsortを使うとindexを返してくれる。

1次元の場合

argsortにより得られたindexを、x[index]の用にするとsortされたデータを作ることができる。
降順にしたい場合は、indexを反転させれば良い。

In [14]: x = np.random.randint(0, 100, size=10)

In [15]: print x
[16 52 64 37 50 68  5 87 99 69]

In [16]: print np.argsort(x)
[6 0 3 4 1 2 5 9 7 8]

In [17]: print x[np.argsort(x)]
[ 5 16 37 50 52 64 68 69 87 99]

In [18]: print x[np.argsort(x)[::-1]]
[99 87 69 68 64 52 50 37 16  5]

多次元の場合

多次元の場合も基本的には1次元と同じ。
ただし、得られたindexをそのままx[index]のようにしてもうまくいかないので、
下記のように一つ一つ渡してデータを取り出すと良い。


In [31]: x = np.random.randint(0, 100, size=(2,10))

In [32]: print x
[[31 72 21 18 47 33 88 12 92 19]
 [55 62 19 69 43 65 95 28 20 33]]

In [33]: index = np.argsort(x)

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

In [35]: print np.array([x[0,index[0,:]],x[1,index[1,:]]])
[[12 18 19 21 31 33 47 72 88 92]
 [19 20 28 33 43 55 62 65 69 95]]

In [36]: print np.array([x[0,index[0,::-1]],x[1,index[1,::-1]]])
[[92 88 72 47 33 31 21 19 18 12]
 [95 69 65 62 55 43 33 28 20 19]]

transpose

numpy.transpose(a, axes=None)

転置したデータが欲しい場合は、transposeかTを使うと良い。
得られるデータは、軸が反転した形になっている。
例えば2次元データAの時には、transposeしたTAは、下記のようになる。
TA[x,y] = A[y,x]
3次元以上でも同じように変換される。
TA[x,y,z] = A[z,y,x]

In [38]: x = np.array([[0,1,2]])

In [39]: print x
[[0 1 2]]

In [40]: print x.T
[[0]
 [1]
 [2]]

In [41]: x = np.array(range(4)).reshape(2,2)

In [42]: print x
[[0 1]
 [2 3]]

In [43]: print x.transpose()
[[0 2]
 [1 3]]

下記は3次元の場合でindexを反転させて渡すと同じ値が得られるのがわかる。

In [44]: x = np.array(range(8)).reshape(2,2,2)

In [45]: xT = x.T

In [46]: print 'x', x
x [[[0 1]
  [2 3]]

 [[4 5]
  [6 7]]]

In [47]: print 'x.T', xT
x.T [[[0 4]
  [2 6]]

 [[1 5]
  [3 7]]]

In [48]: idx = np.array([[i//4,(i//2)%2,i%2] for i in range(8)])

In [49]: x[idx[:,0],idx[:,1],idx[:,2]]
Out[49]: array([0, 1, 2, 3, 4, 5, 6, 7])

In [50]: xT[idx[:,2],idx[:,1],idx[:,0]]
Out[50]: array([0, 1, 2, 3, 4, 5, 6, 7])

並び替える順番を指定する場合

transposeでは並び替える軸の順番を指定することができる。

下記は2,0,1の順番に変換した場合の例。
これはRGBRGBと並んでいるInterleaved配列の画像データをR, G, B のようにPlane配列にする場合に有効。

In [53]: print x
[[[0 1]
  [2 3]]

 [[4 5]
  [6 7]]]

In [54]: print x.transpose(2,0,1)
[[[0 2]
  [4 6]]

 [[1 3]
  [5 7]]]
In [63]: I = sp.misc.imread('./data/SIDBA/Lenna.bmp')

In [64]: r, g, b = I.transpose(2,0,1)

In [65]: np.sum(np.abs(r - I[:,:,0])) + np.sum(np.abs(g - I[:,:,1])) + np.sum(np.abs(b - I[:,:,2]))
Out[65]: 0

transpose.png

import matplotlib.pyplot as plt
import matplotlib.cm as cm

fig, axes = plt.subplots(ncols=4, figsize=(12,8))
axes[0].set_title('color')
axes[0].imshow(I)
axes[0].get_xaxis().set_visible(False)
axes[0].get_yaxis().set_visible(False)

axes[1].set_title('R')
axes[1].imshow(r, cmap=cm.Greys_r, vmin=0,vmax=255)
axes[1].get_xaxis().set_visible(False)
axes[1].get_yaxis().set_visible(False)

axes[2].set_title('G')
axes[2].imshow(g, cmap=cm.Greys_r, vmin=0,vmax=255)
axes[2].get_xaxis().set_visible(False)
axes[2].get_yaxis().set_visible(False)

axes[3].set_title('B')
axes[3].imshow(b, cmap=cm.Greys_r, vmin=0,vmax=255)
axes[3].get_xaxis().set_visible(False)
axes[3].get_yaxis().set_visible(False)

roll

numpy.roll(a, shift, axis=None)
配列の要素を回転させる

1次元の場合

sign direction
+ forward
- backward
In [88]: x = np.arange(10)

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

In [90]: print np.roll(x, 1)
[9 0 1 2 3 4 5 6 7 8]

In [91]: print np.roll(x, -1)
[1 2 3 4 5 6 7 8 9 0]

多次元の場合

axisによって、回転させる軸を選ぶことができる。
なにも指定しない場合は、flatにされた後に回転して元のshapeに戻す

In [92]: x = np.arange(20).reshape(2,10)

In [93]: print x
[[ 0  1  2  3  4  5  6  7  8  9]
 [10 11 12 13 14 15 16 17 18 19]]

In [94]: print np.roll(x, 2)
[[18 19  0  1  2  3  4  5  6  7]
 [ 8  9 10 11 12 13 14 15 16 17]]

In [95]: print np.roll(x, 1, axis=0)
[[10 11 12 13 14 15 16 17 18 19]
 [ 0  1  2  3  4  5  6  7  8  9]]

In [96]: print np.roll(x, 1, axis=1)
[[ 9  0  1  2  3  4  5  6  7  8]
 [19 10 11 12 13 14 15 16 17 18]]

rollaxis

numpy.rollaxis(a, axis, start=0)

aの各次元の大きさを並べ替える
ex.)
aが2次元で3x4だとしたときに、4x3にするとか。

動きとしては、axisをstartの位置まで移動させます。

直感的にわかりづらいですが、一つ一つ処理を分解すると下記のような処理になります。

a.shape が(3,4,5,6)の4次元としたときに
np.rollaxis(a, axis=3, start=1)

  1. axes = list(range(a.ndim)) ... [0,1,2,3]
  2. axes.remove(axis) ... [0,1,2]
  3. axes.insert(start, axis) ... [0,3,1,2]
  4. return a.transpose(axes) ... a.shape (3,6,4,5)

これは、axis番目の次元の大きさを取り出して、start番目のところに入れるという処理になります。

In [15]: x = np.arange(3*4*5*6).reshape(3,4,5,6)

In [16]: print x.shape
(3, 4, 5, 6)

In [17]: print np.rollaxis(x, 3, 1).shape
(3, 6, 4, 5)

a.shape が(3,4,5,6)の4次元としたときに
np.rollaxis(a, axis=1, start=3)

  1. axes = list(range(a.ndim)) ... [0,1,2,3]
  2. axes.remove(axis) ... [0,2,3]
  3. axes.insert(start, axis) ... [0,2,1,3] ... 入れる場所に注意
  4. return a.transpose(axes) ... a.shape (3,5,4,6)
print np.rollaxis(x, 1, 3).shape
(3, 5, 4, 6)

swapaxes

numpy.swapaxes(a, axis1, axis2)

axis1,axis2を入れ替える

In [4]: x = np.arange(3*4).reshape(3,4)

In [5]: x
Out[5]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

In [6]: y = np.swapaxes(x,0,1)

In [7]: y
Out[7]: 
array([[ 0,  4,  8],
       [ 1,  5,  9],
       [ 2,  6, 10],
       [ 3,  7, 11]])
74
81
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
74
81