サムネがコーヒーの記事は書きかけです。

辞書のソート

pythonで辞書のソートを行う方法を置いておきます。

今回は以下の行列について、ガウス-ジョルダン変形を行う際について考えます。

$\begin {pmatrix}3&-3&-1&2\\ 0&0&-5&10\\ 0&4&-12&24 \\0&4&-2&5\end{pmatrix}$

変形の一部として、行の0の個数に応じて行を以下のようにソートする必要があります。

$\begin {pmatrix}3&-3&-1&2\\ 0&4&-12&24\\ 0&4&-2&5\\ 0&0&-5&10\end{pmatrix}$

外部関数

get_zerosという関数を定義して、列のスワップの基準となる0の個数を求めます。

def get_zeros(row:np.ndarray) -> int:
    for i in range(len(row)):
        if row[i] != 0:
            return i
    return len(row)

λを使用した方法

以下のように、λ式を使用して一発で辞書をソートすることができます。

A = np.array([[  3,  -3,  -1,  2],
 [  0,   0,  -5, 10 ],
 [  0,   4, -12, 24],
 [  0,   4,  -2,   5]])

d = {i:get_zeros(n) for i,n in enumerate(A)}

sorted_d = sorted(d.items(), key=lambda x:x[1])
>>>
[(0, 0), (2, 1), (3, 1), (1, 2)]

ndarrayの行スワップを使用して、配列を入れ替えます。

A = A[[i[0] for i in sorted_d]]
>>>
[[  3  -3  -1   2]
 [  0   4 -12  24]
 [  0   4  -2   5]
 [  0   0  -5  10]]

自力で実装

上記のλ式でも十分実用可能ですが、スワップ回数を求めたいときは少し不便です。そのため、自力で辞書のソートを実装していきます。

d = {i:get_zeros(n) for i,n in enumerate(A)}

def sort_d(d:dict):
    items = list(d.items())
    n_swapped = 0
    swapped = True
    while swapped:
        swapped = False
        n_swapped+=1
        for i in range(len(items)-1):
            if items[i][1] > items[i+1][1]:
                tmp = items[i]
                items[i] = items[i+1]
                items[i+1] = tmp
                swapped = True
    return items , n_swapped

sorted_d,n = sort_d(d)

print(d)
print(n)
print(sorted_d)

>>>
{0: 0, 1: 2, 2: 1, 3: 1}
2
[(0, 0), (2, 1), (3, 1), (1, 2)]

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です