numpy の多次元配列を普通にソートすると、列ごと、または行ごとに個別にソートされます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
import numpy as np a = np.array([[100,101,99],[10,3,30],[1000,30,3]]) #------------------------------- # array([[ 100, 101, 99], # [ 10, 3, 30], # [1000, 30, 3]]) #------------------------------- a.sort(axis=0) #------------------------------- # array([[ 10, 3, 3], # [ 100, 30, 30], # [1000, 101, 99]]) #------------------------------- ↑ ↑ ↑ 個別にソート a.sort(axis=1) #------------------------------- # array([[ 99, 100, 101], ← 個別にソート # [ 3, 10, 30], ← 個別にソート # [ 3, 30, 1000]]) ← 個別にソート #------------------------------- |
行単位で 1 データになるようなケースでは、これだとちょっと困ります。データが散り散りになってしまいます。
特定の列(または行)をソートキーとし、他の項目はソート結果に追随させたい場合、argsort を使って実現できます。
- 目次 -
スポンサーリンク
特定の列(または行)でソート
ソートキーにする列(または行)に argsort をかけ、その結果をインデックスにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
import numpy as np l = np.array([[100,101,99],[10,3,30],[1000,30,3]]) #------------------------------- # array([[ 100, 101, 99], # [ 10, 3, 30], # [1000, 30, 3]]) #------------------------------- # # 先頭の列でソート # l[l[:,0].argsort(), :] #------------------------------- # array([[ 10, 3, 30], # [ 100, 101, 99], # [1000, 30, 3]]) #------------------------------- # # 先頭の行でソート # l[:, l[0,:].argsort()] #------------------------------- # array([[ 99, 100, 101], # [ 30, 10, 3], # [ 3, 1000, 30]]) #------------------------------- |
argsort について
argsort は、ソートの一種です。ソートといえば値を並べ替えるものですが、argsort はちょっと違います。値を並べ替えるのではなく、インデックスで並び順を教えてくれます。
言葉だと判りづらいですが、つまり、次のような配列を返してくれます。
1 2 3 4 5 6 |
[0] 1番小さい値のインデックス [1] 2番目に小さい値のインデックス [2] 3番目に小さい値のインデックス ・ ・ ・ |
例
1 2 3 4 5 6 |
l = np.array([200, 300, 400, 100]) l.argsort() #----------------------------------- # array([3, 0, 1, 2], dtype=int64) #----------------------------------- |