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)]