NumPyの使い方(9) 並べ替えsortなど
NumPyのsortについて。
sort()メソッド | 内部で配列をソート。返り値はNone |
np.sort()関数 | ソート済み配列を返す。元の配列は保存。 |
# coding: utf-8 import numpy as np np.random.seed(1) a1 = np.random.randint(0, 100, 10) print(a1) # [37 12 72 9 75 5 79 64 16 1] a1.sort() print(a1) # [ 1 5 9 12 16 37 64 72 75 79] print(a1.sort()) # None np.random.seed(1) a1 = np.random.randint(0, 100, 10) print(a1) # [37 12 72 9 75 5 79 64 16 1] a2 = np.sort(a1) print(a1) # [37 12 72 9 75 5 79 64 16 1] 元配列は保存 print(a2) # [ 1 5 9 12 16 37 64 72 75 79]
axisオプション
どのaxisでソートするかのオプション
列内でのソートはaxis=0とするか、あるいは単に0
行内でのソートはaxis=1とするか、あるいは単に1
デフォルトは-1で、最後の軸(2次元ならaxis=1)でソート
axisをNoneとすると1次元配列に平坦化。
np.random.seed(1) a3 = np.random.randint(0, 100, (3, 6)) print(a3) # [[37 12 72 9 75 5] # [79 64 16 1 76 71] # [ 6 25 50 20 18 84]] # axis=0 print(np.sort(a3, 0)) # [[ 6 12 16 1 18 5] # [37 25 50 9 75 71] # [79 64 72 20 76 84]] # axis=1 print(np.sort(a3, 1)) # [[ 5 9 12 37 72 75] # [ 1 16 64 71 76 79] # [ 6 18 20 25 50 84]] # axis=-1 print(np.sort(a3, axis=-1)) # [[ 5 9 12 37 72 75] # [ 1 16 64 71 76 79] # [ 6 18 20 25 50 84]] # axisのデフォルトは-1 print(np.sort(a3)) # [[ 5 9 12 37 72 75] # [ 1 16 64 71 76 79] # [ 6 18 20 25 50 84]] # axis=None print(np.sort(a3, axis=None)) # [ 1 5 6 ..., 76 79 84]
kindオプション
ソートに利用するアルゴリズムを選ぶ。デフォルトは'quicksort'
kind | speed | worst case | stable |
'quicksort' | 1 | O(n^2) | × |
'mergesort' | 2 | O(n*log(n) | ○ |
'heapsort' | 3 | O(n*log(n) | × |
stable:等しい要素の並び順を保存
orderオプション
フィールドをもつ要素のばあい、キーとするフィールドを指定できる。
dtype = [("name", 'U10'), ("height", int), ("age", int)] values = [("香川", 165, 48), ("秋山", 175, 32), ("長田", 170, 27)] a1 = np.array(values, dtype=dtype) print(a1) # [('香川', 165, 48) ('秋山', 175, 32) ('長田', 170, 27)] print(a1.dtype) # [('name', '<U10'), ('height', '<i4'), ('age', '<i4')] print(np.sort(a1, order="age")) # [('長田', 170, 27) ('秋山', 175, 32) ('香川', 165, 48)]
逆順ソート
降順配列にするには
array[::-1] 行を逆順にする array[:, ::-1] 列を逆順にする
などのスライスを使う。
np.random.seed(1) a3 = np.random.randint(0, 100, (3, 6)) print(a3) # [[37 12 72 9 75 5] # [79 64 16 1 76 71] # [ 6 25 50 20 18 84]] # axis=0の逆順ソート print(np.sort(a3, 0)[::-1]) # [[79 64 72 20 76 84] # [37 25 50 9 75 71] # [ 6 12 16 1 18 5]] # axis=1の逆順ソート print(np.sort(a3, 1)[:, ::-1]) # [[75 72 37 12 9 5] # [79 76 71 64 16 1] # [84 50 25 20 18 6]]
argsort()
argsort()はソートした場合のindex番号の配列を取得する。
1次元配列の場合
a1 = np.array([37, 12, 72, 9, 75, 5]) # argsort()...ソートした場合のindex番号を配列にする indexer = a1.argsort() print(indexer) # [5 3 1 0 2 4] a1[5] < a1[3] < a1[1] < a1[0] ... print(a1[indexer]) # [ 5 9 12 37 72 75]
2次元配列の場合は、argsort()でキーとする行の指定ができる。
np.random.seed(1) a1 = np.random.randint(0, 100, (3, 6)) print(a1) # [[37 12 72 9 75 5] # [79 64 16 1 76 71] # [ 6 25 50 20 18 84]] #0行目をキーとしてソート print(a1[:, a1[0].argsort()]) # [[ 5 9 12 37 72 75] # [71 1 64 79 16 76] # [84 20 25 6 50 18]] #1行目をキーとしてソート print(a1[:, a1[1].argsort()]) # [[ 9 72 12 5 75 37] # [ 1 16 64 71 76 79] # [20 50 25 84 18 6]]
argsortにもaxis, kind, orderオプションがある。
lexsort()
複数のキーで間接ソートするときに使う。
lexsort()もargsort()同様にインデックスの配列を得る。
last_name = ["はつね", "さとう", "しまだ", "さとう"] first_name = ["みく", "めぐみ","なおみ", "かな"] indexer = np.lexsort((first_name, last_name)) print(indexer) # [3 1 2 0 ] name =[(last_name[i], first_name[i]) for i in indexer] print(name) # [('さとう', 'かな'), ('さとう', 'めぐみ'), ('しまだ', 'なおみ'), ('はつね', 'みく')]
searchsorted()
ソートされた配列内で二分探索をし、挿入される位置を返す。
a1 = np.array([0, 5, 10, 15, 20]) print(a1.searchsorted(7)) # 2 print(a1.searchsorted(18)) # 4 print(a1.searchsorted(5)) # 1 print(a1.searchsorted([7, 18, 5])) # [2 4 1]
sideオプション:同じ値が複数あるとき、
'left' もっとも左のインデックス。(デフォルト)
'right' もっとも右のインデックス
a1 = np.array([1, 1, 1, 2, 2, 2]) print(a1.searchsorted([1, 2])) # [0 3] print(a1.searchsorted([1, 2], side="right")) # [3 6]
np.unique()
1次元の配列から重複を取り除き、ソートした配列を返す。
python標準のsorted(set(seq))と同様の働き。
a1 = np.array([1, 3, 2, 0, 1, 2, 2, 1]) print(np.unique(a1)) # [0 1 2 3]
return_index=Trueとすると初回のインデックスを返す。
return_counts=Trueとすると、重複している回数を返す。
print(np.unique(a1, return_index=True)) # (array([0, 1, 2, 3]), array([3, 0, 2, 1], dtype=int32)) print(np.unique(a1, return_counts=True)) # (array([0, 1, 2, 3]), array([1, 3, 3, 1]))