pythonを用いて多次元の配列を同時にソートする
目的
複数の配列をある軸を基準にして同時ソートする.
pythonの組み込み関数zip()の説明
やりたいこと
rects = [
[10,20,100,200],
[11,21,110,210],
[12,22,120,220],
[13,23,130,230]
]
classes = ["woman", "man", "woman", "man"]
scores = [0.5, 0.2, 0.9, 0.3]
上記のような多次元配列reactsとclassesを確信度スコアscoreを基準にして並び替える
まずは下準備: zip()とは
Pythonの組み込み関数zip()は複数のイテラブルオブジェクト(リストやタプルなど)の要素をまとめる関数。forループで複数のリストの要素を取得する際などに使う。
forループの中で複数のイテラブルオブジェクト(リストやタプルなど)の要素を同時に取得して使いたい場合は、zip()関数の引数にそれらを指定する。
names = ['Alice', 'Bob', 'Charlie']
ages = [24, 50, 18]
for name, age in zip(names, ages):
print(name, age)
結果
Alice 24
Bob 50
Charlie 18
補足:
zipでひとまとめにする要素の数が異なるときはzip_longest()を用いる. fillvalueを使うとNoneではなく指定したではなく指定した値を入れることができる.
# zip_longest
names = ['Alice', 'Bob', 'Charlie', 'Dave']
ages = [24, 50, 18]
for name, age in zip_longest(names, ages, fillvalue=20):
print(name, age)
結果
Alice 24
Bob 50
Charlie 18
Dave 20
pythonリストの複数同時ソート
#基準にしたいものを一番左に持ってきてzip化する
zip_list = zip(scores, classes, rects)
#昇順にソートする(小 -> 大)
zip_sort = sorted(zip_list)
#降順にソート(大 -> 小)するときはreversa=Trueとする
zip_sort = sorted(zip_lists, reverse=True)
#zipを解凍?する
scores_new, classes_new, rects_new = zip(*zip_sort)
print("scores :", scores_new)
print("classes:", classes_new)
print("rects :", rects_new)
結果
scores : (0.2, 0.3, 0.5, 0.9)
classes: ('man', 'man', 'woman', 'woman')
rects : ([11, 21, 110, 210], [13, 23, 130, 230], [10, 20, 100, 200], [12, 22, 120, 220])
numpyarray(配列)のソート
import numpy as np
#numpy arrayに変換する
scores_np = np.array(scores)
classes_np = np.array(classes)
rects_np = np.array(rects)
#argsort()を用いることで昇順のインデックスを得る
sorted_idx = np.argsort(scores_np)
print("sorted_idx", soeted_idx)
#降順のインデックを得るときは引数に-を加える
sorted_idx = np.argsort(-scores_np)
#各配列をインデックスをもとにして並び替える
scores_np = scores_np[sorted_idx]
rects_np = rects_np[sorted_idx]
classes_np = classes_np[sorted_idx]
print("scores_np :", scores_np)
print("rects_np :", rects_np)
print("classes_np :", classes_np)
結果
sorted_idx [2 0 3 1]
scores_np [0.9 0.5 0.3 0.2]
classes_np ['woman' 'woman' 'man' 'man']
rects_np [[ 12 22 120 220]
[ 10 20 100 200]
[ 13 23 130 230]
[ 11 21 110 210]]
最後に
この記事はこちらを参考にさせていただきました. ありがとうございました.