tqdmでプログレスバーを出す
pythonのtqdm
ライブラリを試す。
tqdmとは
何かしらの処理に対する進捗をプログレスバーとして表示するライブラリ。
loop処理
基本的な使い方として、繰り返し処理の1loop毎にプログレスバーを更新することができる。
イメージとしては、通常の繰り返し処理コードに対して全数を表す部分をtqdm
関数で囲いこむだけでプログレスバーを作成することができる。
range
での繰り返し
import time import pandas as pd from tqdm import tqdm # 通常 for i in range(100): time.sleep(0.1) # tqdm for i in tqdm(range(100)): time.sleep(0.1)
list
取り出しでの繰り返し
import time import pandas as pd from tqdm import tqdm # 通常 for i in list([1, 2, 3, 4]): time.sleep(1) # tqdm for i in tqdm(list([1, 2, 3, 4])): time.sleep(1)
pandas.apply処理
tqdm.pandas()
コードを走らせると、pandas.apply
と同じ使い方のままでプログレスバーが表示されるprogress_apply
が使えるようになる。
apply
は1行(列)毎に関数処理をおこなうメソッドなので、1行(列)処理する毎にプログレスバーが進む。
tqdm.pandas() # progress_applyを取得 df = pd.DataFrame(list(range(10000))) # 通常 df.apply(lambda x: x ** 2, axis=1) # tqdm df.progress_apply(lambda x: x ** 2, axis=1)
jupyter notebook用
tqdm_notebook
を用いることで、通常のtqdm
と同様の処理でjupyte notebook(lab)用の表示ができる。
===========2021/06/16追記============
from tqdm import tqdm_notebook
は近々廃止され、from tqdm.notebook import tqdm
になるそうです。
てか記事を書いた段階でわかってしかるべきだったが調べた情報が古かったというか、一時ソースで読まないといけないなーと反省(しつつ、参考サイトは二次ソース)。
from tqdm import tqdm # 通常 from tqdm import tqdm_notebook as tqdm_nb # notebook用 # 通常tqdm for i in tqdm(range(100)): time.sleep(0.1) # notebook用 tqdm for i in tqdm_nb(range(100)): time.sleep(0.1)
ただし、progress_apply
には対応していなかったり、全く同じ処理ができるわけではないので注意。
notebookに表示すると見づらくなることも多いので、対応してない場合のみtqdm
を使う使い分けか?
後述するが、loopが多い場合は1loopが終わる毎にプログレスバーを消しオプションがあるが、tqdm
はnotebookだと消えずに全て表示されて、表示が冗長になるのでtqdm_notebook
の方が圧倒的に使いやすい。
カスタマイズ
以下の記事を参考にする。
なお、今回notebookを使っているのでtqdm_nb
としているが、説明ではtqdm
と表記する。
loopのはじめにtqdm
をwith
指定すると、以降のloop処理が自動でプログレスバーが表示される。
total
引数で全体の数を指定できる。update
関数を用いることでそのプログレスバーを進めることができる。
プログレスバーの数値は、total
が分母でupdate
が分子として計算される。
プログレスバーは、 例えば2重loopの際に各with
時にas
でそれぞれ名前をつけるとそれぞれ別のプログレスバーとして進捗をチェックすることができる。
また、プログレスバーの前後にある文はそれぞれ set_description
, set_postfix
で変えることができる。
with tqdm_nb(total=100) as pbar1: # プログレスバー1 for i in range(100): pbar1.set_description(f'プログレスバー1-{i}') # プログレスバー1の手前の表示文字 pbar1.set_postfix(progress=i) # プログレスバー1の末尾の表示文字 pbar1.update(1) # プログレスバー1を1/10進める with tqdm_nb(total=100, leave=False) as pbar2: # プログレスバー1。leaveで100%後に消えるかどうか指定 for j in range(100): pbar2.set_description(f'プログレスバー2-{i}') # プログレスバー2の手前の表示文字 time.sleep(0.01) pbar2.update(1) # プログレスバー2を1/10進める pbar2.set_postfix(progress=j) # プログレスバー2の末尾の表示文字
なお、1loop内で処理ごとに進捗を進める、例えばloop内で1処理したら1%、次の処理で2%...のようなこともできる。 例えば、機械学習モデルにおいて、各pipeline毎にかかる時間をざっくり先に計算しておき、それぞれでプログレスバーを進めると便利。
with tqdm_nb(total=50) as pbar1: for i in range(10): pbar1.set_description(f'プログレスバー1-{i}') pbar1.set_postfix(progress=i) time.sleep(1) pbar1.update(1) # プログレスバーを1/50進める time.sleep(1) pbar1.update(4) # プログレスバー1を4/50進める