閉じる

tqdmの使い方まとめ(Pythonで長い処理の進捗表示)

長い処理を実行している時、いまどのくらい進んでいるのか分からないと不安になります。

Pythonの進捗バー定番ライブラリがtqdmです

たった1行足すだけでループに美しい進捗バーが表示され、残り時間(ETA)や処理速度も分かります。

初心者でも実務でもすぐ使える、基本から実用パターンまでまとめます。

tqdmとは?

tqdmは、ループ処理などの進捗を端末やJupyterに見やすく表示してくれるPythonライブラリです

名前はアラビア語の「進捗」を意味し、英語の「taqaddum」に由来します。

tqdmは何ができる?

tqdmは、イテラブル(例えばrangeやリスト)を包むだけで、バーの進行率、経過時間、残り時間、処理速度(例: it/sやB/s)を自動で表示します。

説明文(desc)や単位(unit)、合計件数(total)などを指定して、視覚的に分かりやすいバーにカスタマイズできます。

Jupyter専用のリッチ表示にも対応しています。

どんな時に使う?

  • データ前処理や特徴量生成のループ
  • WebスクレイピングやAPI呼び出しの繰り返し
  • 大量ファイルの読み書き、ダウンロードの進捗
  • 機械学習の学習ループの進捗や指標表示処理時間が数秒以上かかる繰り返しには、まずtqdmを付けるという習慣が役立ちます。

インストールと基本の使い方

pipでtqdmをインストールする

Pythonが動く環境なら1コマンドで導入できます。

環境ごとのpipの違いを避けるため、python -m pipの形をおすすめします。

Shell
# インストール
python -m pip install -U tqdm

# バージョン確認
python -c "import tqdm, sys; print(tqdm.__version__)"

仮想環境(venv)を使っている場合は、有効化したシェルで実行してください。

基本の使い方

既存のforループのイテラブルをtqdmで包むだけです。

Python
# 基本: ループをtqdmで包む
from time import sleep
from tqdm import tqdm  # 端末向けの基本版

for i in tqdm(range(50)):  # 0〜49の50回ループ
    # ここに時間のかかる処理を書く
    sleep(0.05)  # デモ用に50ms待つ

出力例(端末):

text
100%|████████████████████████████████████████| 50/50 [00:02<00:00, 19.99it/s]

trangeの使い方

rangeを直接置き換えるショートカットがtrangeです。

意味は同じで、見た目がすっきりします。

Python
# trangeはrangeのtqdm版ショートカット
from time import sleep
from tqdm import trange

for i in trange(30):  # range(30) と同じ個数
    sleep(0.05)
実行結果
100%|████████████████████████████████████████| 30/30 [00:01<00:00, 20.01it/s]

説明文(desc)と単位(unit)を付ける

処理内容や単位を表示すると、何をどれだけ進めているかが一目で分かります

Python
from time import sleep
from tqdm import tqdm

# descで説明、unitで単位(件、ファイル、Bなど)を指定
for _ in tqdm(range(100), desc="画像をリサイズ中", unit="枚"):
    sleep(0.02)

# バイト単位のときはunit="B"とunit_scale=Trueで自動スケール(KB/MB)
for _ in tqdm(range(200), desc="ダウンロード中", unit="B", unit_scale=True):
    sleep(0.01)
実行結果
画像をリサイズ中: 100%|██████████████| 100/100 [00:02<00:00, 45.10枚/s]
ダウンロード中: 100%|██████████████| 200/200 [00:02<00:00, 89.3kB/s]

件数が分かる時はtotalを指定する

イテラブル側で件数が分からない(ジェネレータなど)場合でも、合計件数が分かるならtotalを与えるとETAが正確になります。

Python
# 件数が分かるが、イテラブルのlenが取れないケース
from time import sleep
from tqdm import tqdm

def generate_items(n):
    for i in range(n):
        sleep(0.01)
        yield i

N = 120
for _ in tqdm(generate_items(N), total=N, desc="前処理", unit="件"):
    pass
実行結果
前処理: 100%|██████████████████████████████| 120/120 [00:01<00:00, 95.2件/s]

totalを使わず手動更新(update)する方法

アイテムごとに進捗量が異なる場合は、tqdm(total=...)update(n)で手動更新できます。

Python
# 手動でupdateする例(可変ステップ)
from time import sleep
from tqdm import tqdm

sizes = [5, 2, 3, 10]  # 合計進捗量をtotalに
with tqdm(total=sum(sizes), desc="可変ステップ", unit="step") as pbar:
    for s in sizes:
        sleep(0.2)     # 何らかの処理
        pbar.update(s) # sだけ進める
実行結果
可変ステップ: 100%|███████████████████████| 20/20 [00:01<00:00, 16.4step/s]

バーを残さない(leave=False)などの簡単カスタマイズ

終わったバーを消したい時はleave=Falseにします。

幅の自動調整はdynamic_ncols=Trueが便利です。

Windowsの古い端末などで崩れる場合はascii=Trueの疑似バーにできます。

Python
from time import sleep
from tqdm import tqdm

for _ in tqdm(range(80), desc="一時的な処理", leave=False, dynamic_ncols=True, ascii=True):
    sleep(0.01)

主なパラメータの早見表:

パラメータ役割
desc左端に出す説明文desc=”読み込み”
total合計件数(既知なら指定)total=1000
unit, unit_scale単位と自動スケールunit=”B”, unit_scale=True
leave終了後にバーを残すかleave=False
asciiASCIIバーにするascii=True
dynamic_ncols端末幅に合わせて調整dynamic_ncols=True
ncolsバーの固定幅ncols=100
colourバー色(一部環境)colour=”green”
mininterval, miniters更新頻度の抑制mininterval=0.2
disableバー表示を無効化disable=条件式
position複数バーの縦位置position=1
注意

一部環境では色(colour)や絵文字/全角の表示に制限があります。

Jupyterとスクリプトでの表示

スクリプトはtqdm.autoで環境を自動判定

端末やJupyterなど環境に応じて最適表示に切り替えてくれるのがtqdm.autoです。

迷ったらfrom tqdm.auto import tqdm, trangeを基本にすると安全です。

Python
# どの環境でも最適表示にしたい場合
from time import sleep
from tqdm.auto import tqdm, trange

for i in trange(100, desc="auto"):
    sleep(0.01)

Jupyterはtqdm.notebookが見やすい

Jupyterではtqdm.notebookがipywidgetsベースのリッチなバーを表示します。

表示が出ない場合、ipywidgetsのインストールを確認します。

Shell
python -m pip install -U ipywidgets
Python
# Jupyter Notebook/Lab での推奨
from time import sleep
from tqdm.notebook import tqdm

for _ in tqdm(range(50), desc="Notebookバー", unit="it"):
    sleep(0.02)

Jupyterでもtqdm.autoは使えますが、表示品質はtqdm.notebookが最適です。

出力が崩れる時の対処

printとtqdmの行が混ざると崩れやすいです。

以下のコツで安定します。

  • 普通のprintの代わりにtqdm.write()を使う(バーを壊さずにログを出せます)
  • 端末幅による折り返しはdynamic_ncols=Truencols=…で調整
  • 複数バーはpositionで縦位置をずらす
  • どうしても崩れるならascii=Trueにする
Python
from time import sleep
from tqdm import tqdm

for i in tqdm(range(5), desc="処理"):
    sleep(0.2)
    # printの代わりにtqdm.writeを使う
    from datetime import datetime
    tqdm.write(f"[{datetime.now().isoformat(timespec='seconds')}] {i}件目が完了")
実行結果
処理:  20%|██                | 1/5 [00:00<00:00,  4.85it/s]
[2025-09-20T12:34:56] 0件目が完了
処理: 100%|██████████████████| 5/5 [00:01<00:00,  4.85it/s]

よく使う実用例とコツ

enumerateやリスト処理にtqdmを組み合わせる

インデックスが必要ならenumerateと併用します。

合計件数が分かる場合はtotalを付けるとETAが安定します。

Python
from time import sleep
from tqdm import tqdm

items = ["a", "b", "c", "d"]
for idx, item in enumerate(tqdm(items, total=len(items), desc="処理", unit="件")):
    # ここでitemを処理
    sleep(0.1)

リスト内包表記や生成式でも包めます。

Python
from time import sleep
from tqdm import tqdm

def slow_square(x):
    sleep(0.02)
    return x * x

data = list(range(100))
# list(...)で具象化すると全件処理しつつ進捗が見える
squares = [slow_square(x) for x in tqdm(data, desc="二乗", unit="件")]

ファイル処理

大量ファイルの処理やバイト単位の進捗を見たい時に有用です。

フォルダ内の全ファイルを処理

Python
from time import sleep
from pathlib import Path
from tqdm import tqdm

folder = Path(".")
files = list(folder.rglob("*.txt"))  # 先に一覧化して総数を把握
for p in tqdm(files, desc="テキスト処理", unit="ファイル"):
    # 各ファイルに対して何らかの処理
    sleep(0.01)

ダウンロードのバイト進捗を表示(requests)

バイト単位はunit="B"unit_scale=Trueが定番です。

wrapattrを使うとストリームのreadをラップして自動更新できます。

Python
import requests
from tqdm import tqdm

# 100KBのファイルをダウンロードして進捗を表示
url = "https://httpbin.org/bytes/102400"
dest = "download.bin"

chunk_size = 8192 # 任意のチャンクサイズ

with requests.get(url, stream=True) as r:
    r.raise_for_status()
    total = int(r.headers.get("content-length", 0))

    with tqdm.wrapattr(r.raw, "read", total=total, desc="DL", unit="B", unit_scale=True) as f_in:
        with open(dest, "wb") as f_out:
            while chunk := f_in.read(chunk_size):
                f_out.write(chunk)
実行結果
DL: 100%|██████████████████| 100k/100k [00:00<00:00, 191kB/s]

pandasでprogress_applyを使う

pandasのapplyに進捗を出したい時はtqdm.pandas()を一度呼ぶと、progress_applyが使えるようになります。

Python
import time
import pandas as pd
from tqdm.auto import tqdm

tqdm.pandas(desc="行処理中")  # 1回呼び出して登録

df = pd.DataFrame({"x": range(50)})
def slow_op(v):
    time.sleep(0.02)
    return v * 2

# 通常のapplyの代わりにprogress_applyを使う
df["y"] = df["x"].progress_apply(slow_op)
print(df.head())
実行結果
行処理中: 100%|██████████████████████████████| 50/50 [00:01<00:00, 44.3it/s]
   x   y
0  0   0
1  1   2
2  2   4
3  3   6
4  4   8

Jupyterでリッチ表示が出ない場合はipywidgetsを導入してください。

ネストしたループの進捗

外側と内側の2段ループを同時に表示するにはpositionleaveを使います。

外側バーを上(position=0)、内側バーを下(position=1)に配置します。

Python
from time import sleep
from tqdm import tqdm

outer = range(3)
inner = range(5)

outer_bar = tqdm(outer, desc="エポック", position=0)
for i in outer_bar:
    # 内側バーは毎エポックごとに新しく作成し、終わったら消す
    for j in tqdm(inner, desc=f"バッチ", position=1, leave=False):
        sleep(0.05)
        # 指標を動的に表示
        outer_bar.set_postfix(epoch=i, batch=j)
# 明示的に閉じてもOK: outer_bar.close()

出力例(概形):

text
エポック:  67%|████████████████████████      | 2/3 [00:00<00:00,  8.9it/s, epoch=1, batch=4]

遅い処理の見積もり

<tqdm>は自動でETAを出しますが、精度を上げる鍵はtotalを正しく与えることです。

処理時間がばらつく場合は、更新頻度を抑えて落ち着いたETAにできます。

Python
# 変動が大きい処理のETAを見やすくする
import random
from time import sleep
from tqdm import tqdm

N = 100
for i in tqdm(range(N), desc="推定", unit="件", mininterval=0.3, smoothing=0.1):
    # 0.0〜0.1秒のランダムな処理
    sleep(random.random() * 0.1)

さらに、学習の損失やカスタム情報をset_postfixで右側に表示できます。

Python
from time import sleep
from tqdm import trange

for i in trange(20, desc="学習", unit="it"):
    loss = 1.0 / (i + 1)
    sleep(0.05)
    # 小数点桁数などは辞書で渡せば自動整形
    trange.set_postfix = None  # 型ヒント対策(実行時は不要)
Python
# 正しい使い方の例(インスタンスに対して呼ぶ)
from time import sleep
from tqdm import trange

bar = trange(20, desc="学習", unit="it")
for i in bar:
    sleep(0.05)
    loss = 1.0 / (i + 1)
    bar.set_postfix(loss=f"{loss:.3f}")
実行結果
学習:  55%|███████████████▌        | 11/20 [00:00<00:00, 18.8it/s, loss=0.083]

処理が極端に遅くてバー自体の描画が重い場合はminintervalminitersで更新頻度を下げると快適です。

まとめ

tqdmは「forを包むだけ」で進捗バーが手に入る、軽量で強力なユーティリティです。

基本はtqdm(range(...))、説明はdesc、単位はunit、合計が分かればtotalを指定します。

スクリプトならtqdm.auto、Jupyterならtqdm.notebookが見やすく、tqdm.writeでログも安全に併用できます。

ファイルI/O、pandas、ネストしたループ、手動updateまで押さえれば、実務の大半の「長い処理」を安心して回せるようになります

まずは小さなループから導入し、便利さを体感してみてください。

この記事を書いた人
エーテリア編集部
エーテリア編集部

人気のPythonを初めて学ぶ方向けに、文法の基本から小さな自動化まで、実際に手を動かして理解できる記事を書いています。

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!