こんにちは。Toruです。
今回はpythonライブラリ natsortについてお話しします。
データを数字の順に並べたいとき、普通にsortを使うと不自然な並びになることがあるが、natsortを使うことで自然な並びにすることができます。
それでは詳しくみていきましょう。
現状の問題点
例えばファイル名などをソートして順番を揃えたいとき、 sort() を使った場合。
1 2 3 4 5 6 7 8 9 10 11 | import numpy as np num_list = [] for num in range(1, 21, 1) : num_list.append(str(num)) num_list.sort() print(num_list) |
これを実行した結果がこちら。
1 | ['1', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '2', '20', '3', '4', '5', '6', '7', '8', '9'] |
これじゃない。私たちが求めていたのは1, 2, 3, …みたいな、ごく自然な並びなのに。
もう一つ試しに、あるフォルダーの中にあるmnistデータの画像に名前をつけて他のファイルに保存する場合。(今回は、試しに画像サイズを変えて別のフォルダーに保存する。)
■mnist画像を取り出し、指定のフォルダーに保存するプログラム
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import numpy as np import keras from keras.datasets import mnist import matplotlib.pyplot as plt # Download mnist data (x_train, _), (_, _) = mnist.load_data() for i in range(10) : # Show mnist data plt.imshow(x_train[i].reshape((28, 28)), cmap = 'Greys') # Save data plt.savefig('./nat_before/mnist{0}.png'.format(i + 1)) |
■保存されたmnist画像が入っているフォルダー
■mnist画像のサイズを変えて別のフォルダーに保存する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import cv2 import numpy as np import glob # Change data size def resize(img) : image = cv2.resize(img, (500, 500)) return image file_name = glob.glob('./before/*.png') train_num = 1 for file in file_name : img = cv2.imread(file, cv2.IMREAD_GRAYSCALE) resize_image = resize(img) cv2.imwrite('./after/mnist{0}.png'.format(train_num), resize_image) train_num += 1 |
■保存されたmnist画像が入っているフォルダー
この様にbeforeフォルダーに入っていたデータの並びとは全く関係のない並びで保存される。
この状態だと例えば、ファイル名で画像を取り出ししたいとき、自分が思っていない画像が出てくるのでこれをどうにかしたい。
救世主:natsort
そんな状況を回避してくれるのがこのnatsortというやつ。
natsortedとは自然順アルゴリズムでソートしたものをいう。ちなみにコンピュータがソートしたもの(。 )をコンピュータ文字列ソートアルゴリズム
普段私たちが数字を並べた時の並べ方はこの自然順アルゴリズムの並べ方である。
pythonライブラリなのでインストールが必要だが、これらの問題を解決してくれる。まずはいつも通りVSCodeのターミナルからインストール。インストールの方法はこちらの記事から試してください。
インストールが終わったら、 from natsort import natsorted を入れて、 sort() のところを natsorted() に変えてみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 | import numpy as np from natsort import natsorted num_list = [] for num in range(1, 21, 1) : num_list.append(str(num)) natsorted(num_list) print(num_list) |
実行結果
1 | ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20'] |
■mnist画像を取り出し、指定のフォルダーに保存するプログラムの場合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import cv2 import numpy as np import glob from natsort import natsorted def resize(img) : image = cv2.resize(img, (500, 500)) return image file_name = glob.glob('./nat_before/*.png') train_num = 1 for file in natsorted(file_name) : img = cv2.imread(file, cv2.IMREAD_GRAYSCALE) resize_image = resize(img) cv2.imwrite('./nat_after/natsort_mnist{0}.png'.format(train_num), resize_image) train_num += 1 |
■実行後のafterフォルダー内
ちゃんとbeforeフォルダー内と同じ並びとファイル名になっているのが確認できます。
最後に
- 私たちがやっている数字の並べ方は、自然順アルゴリズム(自然順ソート)
- natsort() は自然順アルゴリズム。 sort() はコンピュータ文字列アルゴリズム。
- natsorted() は、’1′, ‘2’, ‘3’, …と並べるのに対し、 sort() は、’1′, ’10’, ’11’, …と並べる。
以上、natsortについて説明しました。使い方もとても簡単なのでぜひ皆さん使ってみてください。
pythonには様々なライブラリが無料で扱えるのでとても便利ですよね。
今後もpythonの便利なライブラリや使い方について紹介していきたいと思いますので今後も期待していてください。
おすすめの書籍
私が大学時代、pythonを使ってディープラーニングを研究していたときにすごく参考になった書籍を紹介します。pythonに興味がある方なら必ず読んだ方が良い内容になっているのでぜひ読んでみてください。
■おすすめ・関連サイト
■参考サイト:
https://pypi.org/project/natsort/
https://qiita.com/peg/items/8bf13cff8259ab464d8b