プログラミング
記事内に商品プロモーションを含む場合があります

【Python】tqdmで進捗バーを表示&カスタマイズする方法

Aru

プログレスバーで進捗状況を表示できるライブラリ「tqdm」の使い方をチートシート形式でまとめました。「説明を追加するにはどうすればいいんだっけ?」とカスタマイズ方法を忘れてしまうことが多いので、今回記事にまとめてみました。この記事では、tqdmの基本的な使い方からカスタマイズの方法までを分かりやすく解説しています。クイックリファレンス的に活用ください。

tqdmとは

Pythonでデータ処理や機械学習を行う際、処理が長時間に及ぶことは珍しくありません。そんなとき、「あとどれくらいで完了するかを把握できれば良いのに」と感じたことはありませんか?

このようなニーズに応え、進捗状況を簡単に可視化してくれるのが「tqdm」です。tqdmを使うと、進行中の処理をプログレスバー形式でリアルタイムに表示でき、処理の進捗度合いや完了までの時間を一目で確認することができるようになります。

tqdmの導入は非常に簡単で、「データ読み込みがどのくらいで終了するか」や「現在の処理がどこまで進んでいるか」を、視覚的に分かりやすく確認することができます。

この記事では、tqdmの基本的な使い方から、より便利に使うためのカスタマイズ方法までを分かりやすくまとめました。

プログレスバーの動作例

tqdmの動作サンプル

インストール

tqdmのインストールはpipで行うことができます。

pip install tqdm

インポート

ライブラリのインポート

tqdmを使う場合は、以下のようにtqdm.tqdmをインポートします。

from tqdm import tqdm

ライブラリのインポート(jupyter notebookの場合)

jupyter notebook, google colabの場合は、tqdmの代わりにtqdm.notebookを利用します。

通常のtqdmでも問題ないことが多いですが、たまに表示がおかしくなりますので、tqdm.notebookを利用することをおすすめします。

Google Colab, Jupyter notebookの場合

from tqdm.notebook import tqdm

基本的な使い方

for文でtqdmを利用する

オーソドックスな使い方だと思います。

for文にtqdm(...)を加えるだけでプログレスバーが表示できます。

rangeで数を指定

for xx in range(..)の形式で利用する場合は、rangeをtqdmで囲むだけです。

from tqdm import tqdm
import time

for i in tqdm(range(100)):
    time.sleep(0.1)
出力結果
プログレスバー(動画)

要素数分だけループ

for xx in リストの形式でも利用することができます。この場合も、tqdmで囲むだけです。

from tqdm import tqdm
import time

x = ['a', 'b', 'c', 'd', 'e', 'f']
for e in tqdm(x):
    time.sleep(1)100%|██████████| 6/6 [00:06<00:00,  1.00s/it
出力結果
100%|██████████| 100/100 [00:10<00:00,  9.81it/s]

with tqdm(…) as …を利用する

プログレスバーに対して、細かな設定をしたい場合は、with tqdm(...) as ...を利用します

更新する刻み(ステップ)を指定しない場合

with tqdm...を使う方法では、pbarでプログレスバーの項目にアクセスできるのが利点です。

なお、この方法で利用する場合は、ループ中にpbar.update()を挿入してプログレスバーを更新する必要があります

from tqdm import tqdm
import time

with tqdm(total = 100) as pbar:
  for i in range(100):
    time.sleep(0.1)
    pbar.update()
出力結果
100%|██████████| 100/100 [00:10<00:00,  9.81it/s]

更新する刻み(ステップ)を指定する場合

pbar.update(val)のようにvalを設定することで、プログレスバーの進捗の更新割合を指定することができます。

以下の例では10刻みでプログレスバーを更新しています。

from tqdm import tqdm
import time

with tqdm(total = 100) as pbar:
  for i in range(10):
    time.sleep(0.1)
    pbar.update(10)
出力結果
100%|██████████| 100/100 [00:01<00:00, 98.42it/s]

プログレスバーに各種情報を表示したい

プログレスバーの表示もカスタマイズすることができます

以下は、プログレスバーに、様々な情報を表示させたい場合の記述方法です

prefix(description):手前に説明を追加

固定した文字列を追加

プログレスバーの手前に文字列を追加する方法です。追加した文字列は更新されません

プログレスバーの手前に名前をつけたい場合は以下のようにdesc=を利用します。

from tqdm import tqdm
import time

for i in tqdm(range(100), desc="SAMPLE"):
    time.sleep(0.1)

また、以下のように記述することもできます。

from tqdm import tqdm
import time

with tqdm(total = 100) as pbar:
  pbar.set_description("SAMPLE") # 説明文を追加
  for i in range(100):
    time.sleep(0.1)
    pbar.update()

以下のように、出力に対して赤文字の部分が追加されます

出力結果
SAMPLE: 100%|██████████| 100/100 [00:10<00:00,  9.81it/s]

実行中に更新

文字列を更新したい場合には、pbar.set_decsription(...)を利用します。

具体的には、以下のようにすることで、表示内容を更新することが可能となります。

from tqdm import tqdm
import time

with tqdm(total = 100) as pbar:
  for i in range(10):
    pbar.set_description(f"[{i}]")
    for j in range(10):
      time.sleep(0.1)
      pbar.update()

実行すると、出力に対して赤文字の部分が追加され、進捗に併せて更新されます。

出力結果
[9]: 100%|██████████| 100/100 [00:10<00:00,  9.84it/s]

postfix(suffix)

辞書型(dict)で渡す場合

値を辞書型で渡すと、key=valueの形式でプログレスバーに表示されます。

from tqdm import tqdm
import time
import random

with tqdm(total = 100) as pbar:
  for i in range(100):
    time.sleep(0.1)
    pbar.set_postfix({"val": random.random()})
    pbar.update()

以下のように、出力に対して赤文字の部分が追加されます

出力結果
100%|██████████| 100/100 [00:10<00:00,  9.67it/s, val=0.709]

文字列で渡す場合

表示する文字列を渡したい場合は、以下のようにします。

from tqdm import tqdm
import time
import random

with tqdm(total = 100) as pbar:
  for i in range(100):
    time.sleep(0.1)
    pbar.set_postfix_str(f"val:{random.random()}")
    pbar.update()

以下のように、出力に対して赤文字の部分が追加されます

出力結果
100%|██████████| 100/100 [00:10<00:00,  9.68it/s, val:0.41087129503640296]

その他

Pandasでプログレスバーを表示

tqdmを使って、pandasのapplyなどでもプログレスバーを表示することが可能です。この場合は、tqdm.pandas()を実行し、その後progress_applyを利用します。

なお、progress_apply以外にも、progress_applymapなどのメソッドも追加されます。

pandasでapplyがどれくらいで終わるかわかるようになるので重宝します。

from tqdm.notebook import tqdm
import pandas as pd
import random

df = pd.DataFrame({"a": [random.random() for i in range(100000)]})

tqdm.pandas()
ave = df['a'].mean()
df['b'] = df['a'].progress_apply(lambda x: x - ave)
display(df.head())
出力結果
pandasでプログレスバー

プログレスバーを表示しながら、ログ表示もしたい

プログレスバーを表示しつつ、ログを表示したい場合があるかと思います。tqdmでは、プログレスバーを出力しならが、ログを出力する機能も備えています。

これには、pbar.writeを利用します

私は、プログレスバーを表示しつつログ表示を多用します。途中経過などを出力するのに便利です

from tqdm import tqdm
import time
import random

with tqdm(total = 10) as pbar:
  for i in range(10):
    time.sleep(0.1)
    r = random.random()
    if r > 0.8:
      pbar.write(f"Update r = {r}")
    pbar.update(1)

pbar.writeで出力したログは、プログレスバーとは別に追加されます。以下の出力結果は、ログを表示した例です。例のように、プログレスバーの下にpbar.writeで出力した文字列が表示されます。

出力結果
プログレスバー(アニメーション)

上の出力結果は、Google Colabで以下のコードを実行した例です。
tqdm.notebookを使っていることに注意してください。

from tqdm.notebook import tqdm
import time
import random

with tqdm(total = 100) as pbar:
  for i in range(100):
    time.sleep(0.1)
    r = random.random()
    if r > 0.8:
      pbar.write(f"Update r = {r}")
    pbar.update()

2重ループ

2重ループの場合は、tqdmを重ねるだけで大丈夫です。

2重ループさせる場合は、プログレスバーがどのループのものかわかるように、descriptionをつけておいた方が良いと思います。

leave=Falseを指定すると、ループ終了時にプログレスバーが削除されます。内側のループは、leave=Falseを指定してループ終了時に消えるようにしておいた方が、進捗が見やすくなります

from tqdm import tqdm
import time

for i in tqdm(range(5), desc="LOOP1"):
    for j in tqdm(range(100), desc="Loop2", leave=False):
         time.sleep(0.01)
出力結果
2重ループ

まとめ

以上、私が利用している範囲でtqdmの使い方をまとめました。随時更新予定ですので、「これを追加してほしい」があればコメントください。

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

ABOUT ME
ある/Aru
ある/Aru
IT&機械学習エンジニア/ファイナンシャルプランナー(CFP®)
専門分野は並列処理・画像処理・機械学習・ディープラーニング。プログラミング言語はC, C++, Go, Pythonを中心として色々利用。現在は、Kaggle, 競プロなどをしながら悠々自適に活動中
記事URLをコピーしました