この記事は, Pythonを利用して研究を行なっていく中で私がつまずいてしまったポイントをまとめていくものです。同じような状況で苦しんでいる方々の参考になれば嬉しいです。Pythonつまずきポイント集の目次は以下のページをご覧ください。
環境
●Ubuntu 16.04
●Python 3.7.3
●conda 4.7.12
●pytorch 1.2.0
目的
エラーは出ないのになぜか結果が悪い。何が原因なのか突き止めたい。
考えられる原因
私の場合は「glob」が悪さをしていました。機械学習などのスクリプトでは,あるディレクトリ(以下)のファイル名を一括して操作したいような場面が多々あります。そのような状況で大活躍するのが「glob」です。
こちらのglobですが,How is Pythons glob.glob ordered?にもある通り,コマンドで「ls -U」を利用した時の順番でファイル名を取得してきます。これは,名前順でも,数字の大小順でもありません。
ですので,例えばディレクトリのファイルを上から順番に操作することを前提としている時に,globを使ってしまうと順番がバラバラになってしまいます。私も,これでかなりハマりました。
エラーが出ないことがあるため,globのソート忘れに関しては原因を突き止めることが難しいのではないかと思います。ただ,一回苦しめば二度と同じ過ちは繰り返さないと誓うほどには痛いミスでした。
解決策としては,以下のように「natsorted」を使うことでGUIで表示される順番と同じようにソートをかけることができます。ちなみに,普通のsortedを利用すると,「1, 2, 10 」をソートすると「1→10→2」となります。これは辞書順ソートなので,数字の代償とは関係ないことに注意してください。natsortedは数字の大小に従ってソートを行います。
import glob
from natsort import natsorted
# dirというディレクトリの下にある「拡張子がtxt」のファイル名を自然順にソート
file_list = natsorted(glob.glob("dir/*.txt"))