
「サイエンティフィックPythonのための」IDE、Spyder上にてScientific Python Lectures様のレクチャ実習中。NumPyの実習5回目です。今回は、Numpy配列の「ソート」です。ソートのアルゴリズムは4種類から選べるみたいだけれども、今回はアルゴリズム以前の操作方法デス。
※「 ソフトな忘却力」投稿順 Index はこちら
※レクチャ実習中といっても、「準拠」しているのはレクチャの章立てくらいです。Scientific Python Lectures様のコースは例題だけでなく、エクササイズなども充実、それを全部順番に解いていったら必ずや立派な人になれるだろ~と思います。でもキチンとやったら、死ぬまでに終わらない、と手抜きを正当化。
ソート対象の配列を作るところから
ソート対象はわかりやすいように整数を並べて、その順番をバラバラにしたものにしたいです。その操作は以下で。
import numpy as np s0 = np.arange(16) np.random.shuffle(s0)
この後でSpyderの変数イクスプローラを眺めれば以下のごとし。
確かに順番が「シャッフル」されているみたい。しかし、それをソートすると元に戻るだけの話なので、2次元の配列にしてみました。こんな感じ。
s1 = s0.reshape((2, 8))
この辺、前回やったところです。メモリ上の配列の実体は一つ、「ビュー」が異なるだけのハズ。念のために確認するとこんな感じ。
メモリはシェアされておる、と。
インプレースのソート
さて、配列s1は2次元配列ですが、s0のビューでしかないです。それを「行内でインプレースにソート」をかけてみます。大丈夫か?
s1.sort(axis=1)
ちゃんと配列s1の行は行内で昇順にソートされておるようです。そして実体メモリであるs0の順番もソートされとります。ビューで見える順番だけでなくメモリ実体もソートされておるようです。インプレースなのね。
アウトプレースなソート、降順
さて、新たな配列s2とs3を作りました。そして、その最大値を与えるインデックスも求めてます。
s2 = np.array([1, 3, 2, 1, 5, 0, 3, 2]) s3 = s2.reshape((2, 4)) s2max = np.argmax(s2) s3max = np.argmax(s3) s3urmax = np.unravel_index(np.argmax(s3, axis=None), s3.shape)
さらに、s3の中で「2より小さい数」に-1を代入という荒業をやってます。s3は「ビュー」なので、s2にも代入されてしまう筈。
s3[s3 < 2] = -1
さてこの状態で s2 について「アウト・プレース」でソートかけてみます。
ソートされとりますが、アウトプレースなので元のs2もs3も揺るぎもしませぬ。
ソートできそうな気がしてきた。ホントか?