tqdm
、「進歩」を意味するアラビア語のtaqaddum (تقدّم) に由来しており、スペイン語 ( te quiero demasiado ) の「とても愛しています」の略語です。
ループにスマートな進行状況メーターを表示させることができます。反復可能オブジェクトをtqdm(iterable)
でラップするだけで完了です。
from tqdm import tqdm
for i in tqdm ( range ( 10000 )):
...
76%|████████████████████████ | 7568/10000 [00:33<00:10, 229.00it/s]
trange(N)
tqdm(range(N))
の便利なショートカットとしても使用できます。
パイプを使用してモジュールとして実行することもできます。
$ seq 9999999 | tqdm --bytes | wc -l
75.2MB [00:00, 217MB/s]
9999999
$ tar -zcf - docs/ | tqdm --bytes --total ` du -sb docs/ | cut -f1 `
> backup.tgz
32% | ██████████▍ | 8.89G/27.9G [00: 42< 01:31, 223MB/s]
オーバーヘッドは低く、反復ごとに約 60 ナノ秒 ( tqdm.gui
の場合は 80 ナノ秒)、パフォーマンスの低下に対して単体テストが行われています。比較すると、定評のある ProgressBar のオーバーヘッドは 800ns/iter です。
オーバーヘッドが低いことに加えて、 tqdm
スマートなアルゴリズムを使用して残り時間を予測し、不要な反復表示をスキップするため、ほとんどの場合、オーバーヘッドは無視できます。
tqdm
、任意のプラットフォーム (Linux、Windows、Mac、FreeBSD、NetBSD、Solaris/SunOS)、任意のコンソールまたは GUI で動作し、IPython/Jupyter ノートブックとも互換性があります。
tqdm
依存関係を必要とせず ( curses
さえも!)、Python とcarriage return r
とline feed n
制御文字をサポートする環境だけが必要です。
目次
contrib
asyncio
logging
のリダイレクトpip install tqdm
プレリリースのdevel
ブランチをプルしてインストールします。
pip install " git+https://github.com/tqdm/tqdm.git@devel#egg=tqdm "
conda install -c conda-forge tqdm
3 つのチャンネルから選択できます。
snap install tqdm # implies --stable, i.e. latest tagged release
snap install tqdm --candidate # master branch
snap install tqdm --edge # devel branch
snap
バイナリは純粋に CLI で使用するため ( import
可能ではない)、 bash
タブ補完が自動的にセットアップされることに注意してください。
docker pull tqdm/tqdm
docker run -i --rm tqdm/tqdm --help
特に CLI で使用する場合、 tqdm
をダウンロードできる他の (非公式) 場所があります。
すべての変更のリストは、GitHub のリリース、wiki、または Web サイトで入手できます。
tqdm
は非常に多用途で、さまざまな方法で使用できます。主なものを以下に 3 つ挙げます。
任意の反復可能オブジェクトをtqdm()
で囲みます。
from tqdm import tqdm
from time import sleep
text = ""
for char in tqdm ([ "a" , "b" , "c" , "d" ]):
sleep ( 0.25 )
text = text + char
trange(i)
tqdm(range(i))
の特別に最適化されたインスタンスです。
from tqdm import trange
for i in trange ( 100 ):
sleep ( 0.01 )
ループ外でインスタンス化すると、 tqdm()
手動で制御できます。
pbar = tqdm ([ "a" , "b" , "c" , "d" ])
for char in pbar :
sleep ( 0.25 )
pbar . set_description ( "Processing %s" % char )
with
ステートメントを使用したtqdm()
更新の手動制御:
with tqdm ( total = 100 ) as pbar :
for i in range ( 10 ):
sleep ( 0.1 )
pbar . update ( 10 )
オプションの変数total
(またはlen()
による反復可能変数) が指定されている場合、予測統計が表示されます。
with
もオプションです (単にtqdm()
変数に代入することもできますが、この場合は最後にdel
またはclose()
を忘れないでください。
pbar = tqdm ( total = 100 )
for i in range ( 10 ):
sleep ( 0.1 )
pbar . update ( 10 )
pbar . close ()
おそらく、 tqdm
の最も素晴らしい使用方法は、スクリプトまたはコマンド ラインでの使用です。 tqdm
(またはpython -m tqdm
) をパイプ間に挿入するだけで、進行状況をstderr
に出力しながら、すべてのstdin
stdout
に通過させます。
以下の例は、タイミング情報を含めて、現在のディレクトリ内のすべての Python ファイルの行数をカウントする方法を示しています。
$ time find . -name ' *.py ' -type f -exec cat { } ; | wc -l
857365
real 0m3.458s
user 0m0.274s
sys 0m3.325s
$ time find . -name ' *.py ' -type f -exec cat { } ; | tqdm | wc -l
857366it [00:03, 246471.31it/s]
857365
real 0m3.585s
user 0m0.862s
sys 0m3.358s
tqdm
の通常の引数も指定できることに注意してください。
$ find . -name ' *.py ' -type f -exec cat { } ; |
tqdm --unit loc --unit_scale --total 857366 >> /dev/null
100% | █████████████████████████████████ | 857K/857K [00: 04< 00:00, 246Kloc/s]
大きなディレクトリをバックアップしますか?
$ tar -zcf - docs/ | tqdm --bytes --total ` du -sb docs/ | cut -f1 `
> backup.tgz
44% | ██████████████▊ | 153M/352M [00: 14< 00:18, 11.0MB/s]
これはさらに美化できます。
$ BYTES= $( du -sb docs/ | cut -f1 )
$ tar -cf - docs/
| tqdm --bytes --total " $BYTES " --desc Processing | gzip
| tqdm --bytes --total " $BYTES " --desc Compressed --position 1
> ~ /backup.tgz
Processing: 100% | ██████████████████████ | 352M/352M [00: 14< 00:00, 30.2MB/s]
Compressed: 42% | █████████▎ | 148M/352M [00: 14< 00:19, 10.9MB/s]
または、7-zip を使用してファイル レベルで実行します。
$ 7z a -bd -r backup.7z docs/ | grep Compressing
| tqdm --total $( find docs/ -type f | wc -l ) --unit files
| grep -v Compressing
100% | ██████████████████████████▉ | 15327/15327 [01: 00< 00:00, 712.96files/s]
基本的な進行状況情報をすでに出力している既存の CLI プログラムは、 tqdm
の--update
および--update_to
フラグの恩恵を受けます。
$ seq 3 0.1 5 | tqdm --total 5 --update_to --null
100% | ████████████████████████████████████ | 5.0/5 [00: 00< 00:00, 9673.21it/s]
$ seq 10 | tqdm --update --null # 1 + 2 + ... + 10 = 55 iterations
55it [00:00, 90006.52it/s]
最も一般的な問題は、整然とした 1 行の進行状況バーではなく、複数行の過剰な出力に関連しています。
CR
、 r
) のサポートが必要です。r
適切にサポートしていない一部のクラウド ロギング コンソール (cloudwatch、K8s) では、 export TQDM_POSITION=-1
の恩恵を受ける可能性があります。colorama
必要になる場合があります。ascii
のみのバーです。tqdm
そうではありません。tqdm(enumerate(...))
をenumerate(tqdm(...))
またはtqdm(enumerate(x), total=len(x), ...)
に置き換えます。同じことがnumpy.ndenumerate
にも当てはまります。tqdm(zip(a, b))
zip(tqdm(a), b)
またはzip(tqdm(a), tqdm(b))
に置き換えます。itertools
にも当てはまります。tqdm.contrib
の下にあります。docker-compose up
およびtty: true
の代わりにdocker-compose run
を使用します。export TQDM_MININTERVAL=5
。このオーバーライド ロジックは、 tqdm.utils.envwrap
デコレーターによって処理されます ( tqdm
とは独立して役立ちます)。他に問題が発生した場合は、参照してファイルしてください。
(2016 年 5 月 19 日以降)
class tqdm ():
"""
Decorate an iterable object, returning an iterator which acts exactly
like the original iterable, but prints a dynamically updating
progressbar every time a value is requested.
"""
@ envwrap ( "TQDM_" ) # override defaults via env vars
def __init__ ( self , iterable = None , desc = None , total = None , leave = True ,
file = None , ncols = None , mininterval = 0.1 ,
maxinterval = 10.0 , miniters = None , ascii = None , disable = False ,
unit = 'it' , unit_scale = False , dynamic_ncols = False ,
smoothing = 0.3 , bar_format = None , initial = 0 , position = None ,
postfix = None , unit_divisor = 1000 , write_bytes = False ,
lock_args = None , nrows = None , colour = None , delay = 0 ):
プログレスバーで装飾することが反復可能です。アップデートを手動で管理するには、空白のままにします。
プログレスバーのプレフィックス。
予想される反復回数。指定しない場合、可能であれば len(iterable) が使用されます。 float("inf") の場合、または最後の手段として、基本的な進行状況統計のみが表示されます (ETA や進行状況バーは表示されません)。 gui
が True で、このパラメータを後で更新する必要がある場合は、最初に任意の大きな正の数 (9e9 など) を指定します。
[デフォルト: True] の場合、反復の終了時にプログレスバーのすべてのトレースが保持されます。 None
の場合、 position
が0
場合にのみ終了します。
io.TextIOWrapper
またはio.StringIO
(オプション)進行状況メッセージを出力する場所を指定します (デフォルト: sys.stderr)。 file.write(str)
とfile.flush()
メソッドを使用します。エンコードについては、 write_bytes
参照してください。
出力メッセージ全体の幅。指定した場合、この境界内に収まるようにプログレスバーのサイズが動的に変更されます。指定しない場合、環境幅の使用が試行されます。フォールバックは 10 メートル幅で、カウンターと統計に制限はありません。 0 の場合、メーターは表示されません (統計のみ)。
進行状況表示の最小更新間隔 [デフォルト: 0.1] 秒。
進行状況表示の最大更新間隔 [デフォルト: 10] 秒。長い表示更新ラグの後、 mininterval
に対応するようにminiters
自動的に調整します。 dynamic_miniters
またはモニター スレッドが有効な場合にのみ機能します。
進行状況表示の最小更新間隔 (反復単位)。 0 およびdynamic_miniters
の場合、等しいmininterval
に自動的に調整されます (CPU 効率が向上し、タイトなループに適しています)。 > 0 の場合、指定された反復回数の表示をスキップします。非常に効率的なループを得るには、これとmininterval
調整します。速い反復と遅い反復 (ネットワーク、項目のスキップなど) の両方で進行状況が不安定な場合は、miniters=1 を設定する必要があります。
指定されていない場合、または False の場合は、Unicode (スムーズ ブロック) を使用してメーターを埋めます。フォールバックは、ASCII 文字「123456789#」を使用することです。
プログレスバーラッパー全体を無効にするかどうか [デフォルト: False]。 [なし] に設定すると、非 TTY で無効になります。
各反復の単位を定義するために使用される文字列 [デフォルト: it]。
1 または True の場合、反復回数は自動的に削減/スケーリングされ、国際単位系標準に準拠したメートルの接頭辞 (キロ、メガなど) が追加されます [デフォルト: False]。他のゼロ以外の数値の場合、 total
とn
スケールされます。
設定すると、常にncols
とnrows
環境に合わせて変更します (ウィンドウのサイズ変更が可能になります) [デフォルト: False]。
速度推定の指数移動平均平滑化係数 (GUI モードでは無視されます)。範囲は 0 (平均速度) ~ 1 (現在/瞬間速度) [デフォルト: 0.3]。
カスタムの棒文字列の書式設定を指定します。パフォーマンスに影響を与える可能性があります。 [デフォルト: '{l_bar}{bar}{r_bar}']、l_bar='{desc}: {percentage:3.0f}%|'そして r_bar='| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, '{rate_fmt}{postfix}]' 可能な変数: l_bar、bar、r_bar、n、n_fmt、total、total_fmt、percentage、elapsed、elapsed_s、ncols 、nrows、desc、unit、rate、rate_fmt、 rate_noinv、rate_noinv_fmt、rate_inv、rate_inv_fmt、postfix、unit_divisor、remaining、remaining_s、eta。 {desc} が空の場合、後続の「:」は自動的に削除されることに注意してください。
カウンタの初期値。プログレスバーを再開するときに便利です [デフォルト: 0]。 float を使用する場合は、 bar_format
で{n:.3f}
などを指定するか、 unit_scale
を指定することを検討してください。
このバーを印刷するためのライン オフセットを指定します (0 から開始)。指定しない場合は自動です。複数のバーを一度に管理するのに便利です (スレッドからなど)。
*
、オプションバーの最後に表示する追加の統計を指定します。可能であればset_postfix(**postfix)
を呼び出します (dict)。
[デフォルト: 1000]、 unit_scale
が True でない限り無視されます。
バイトを書き込むかどうか。 If (デフォルト: False) は Unicode を書き込みます。
中間出力 (初期化、反復、および更新) のrefresh
に渡されます。
画面の高さ。指定すると、この境界の外側にあるネストされたバーが非表示になります。指定しない場合は、環境の高さを使用しようとします。フォールバックは 20 です。
バーの色 (例: 'green'、'#00ff00')。
[デフォルト: 0] 秒が経過するまで表示しません。
delim
が指定されている場合に使用される文字列バッファ サイズ (バイト単位) [デフォルト: 256]。delim
無視し、デフォルトのunit_scale
を True に、 unit_divisor
1024 に、 unit
を 'B' に設定します。stdin
stderr
とstdout
両方に渡します。update()
に渡す数値として扱います。すべての入力を数値としてデコードする必要があるため、これは遅い (~2e5 it/s) ことに注意してください。self.n
に割り当てる数値として扱われます。すべての入力を数値としてデコードする必要があるため、これは遅い (~2e5 it/s) ことに注意してください。 class tqdm ():
def update ( self , n = 1 ):
"""
Manually update the progress bar, useful for streams
such as reading files.
E.g.:
>>> t = tqdm(total=filesize) # Initialise
>>> for current_buffer in stream:
... ...
... t.update(len(current_buffer))
>>> t.close()
The last line is highly recommended, but possibly not necessary if
``t.update()`` will be called in such a way that ``filesize`` will be
exactly reached and printed.
Parameters
----------
n : int or float, optional
Increment to add to the internal counter of iterations
[default: 1]. If using float, consider specifying ``{n:.3f}``
or similar in ``bar_format``, or specifying ``unit_scale``.
Returns
-------
out : bool or None
True if a ``display()`` was triggered.
"""
def close ( self ):
"""Cleanup and (if leave=False) close the progressbar."""
def clear ( self , nomove = False ):
"""Clear current bar display."""
def refresh ( self ):
"""
Force refresh the display of this bar.
Parameters
----------
nolock : bool, optional
If ``True``, does not lock.
If [default: ``False``]: calls ``acquire()`` on internal lock.
lock_args : tuple, optional
Passed to internal lock's ``acquire()``.
If specified, will only ``display()`` if ``acquire()`` returns ``True``.
"""
def unpause ( self ):
"""Restart tqdm timer from last print time."""
def reset ( self , total = None ):
"""
Resets to 0 iterations for repeated use.
Consider combining with ``leave=True``.
Parameters
----------
total : int or float, optional. Total to use for the new bar.
"""
def set_description ( self , desc = None , refresh = True ):
"""
Set/modify description of the progress bar.
Parameters
----------
desc : str, optional
refresh : bool, optional
Forces refresh [default: True].
"""
def set_postfix ( self , ordered_dict = None , refresh = True , ** tqdm_kwargs ):
"""
Set/modify postfix (additional stats)
with automatic formatting based on datatype.
Parameters
----------
ordered_dict : dict or OrderedDict, optional
refresh : bool, optional
Forces refresh [default: True].
kwargs : dict, optional
"""
@ classmethod
def write ( cls , s , file = sys . stdout , end = " n " ):
"""Print a message via tqdm (without overlap with bars)."""
@ property
def format_dict ( self ):
"""Public API for read-only member access."""
def display ( self , msg = None , pos = None ):
"""
Use ``self.sp`` to display ``msg`` in the specified ``pos``.
Consider overloading this function when inheriting to use e.g.:
``self.some_frontend(**self.format_dict)`` instead of ``self.sp``.
Parameters
----------
msg : str, optional. What to display (default: ``repr(self)``).
pos : int, optional. Position to ``moveto``
(default: ``abs(self.pos)``).
"""
@ classmethod
@ contextmanager
def wrapattr ( cls , stream , method , total = None , bytes = True , ** tqdm_kwargs ):
"""
stream : file-like object.
method : str, "read" or "write". The result of ``read()`` and
the first argument of ``write()`` should have a ``len()``.
>>> with tqdm.wrapattr(file_obj, "read", total=file_obj.size) as fobj:
... while True:
... chunk = fobj.read(chunk_size)
... if not chunk:
... break
"""
@ classmethod
def pandas ( cls , * targs , ** tqdm_kwargs ):
"""Registers the current `tqdm` class with `pandas`."""
def trange ( * args , ** tqdm_kwargs ):
"""Shortcut for `tqdm(range(*args), **tqdm_kwargs)`."""
def tqdm . contrib . tenumerate ( iterable , start = 0 , total = None ,
tqdm_class = tqdm . auto . tqdm , ** tqdm_kwargs ):
"""Equivalent of `numpy.ndenumerate` or builtin `enumerate`."""
def tqdm . contrib . tzip ( iter1 , * iter2plus , ** tqdm_kwargs ):
"""Equivalent of builtin `zip`."""
def tqdm . contrib . tmap ( function , * sequences , ** tqdm_kwargs ):
"""Equivalent of builtin `map`."""
class tqdm . notebook . tqdm ( tqdm . tqdm ):
"""IPython/Jupyter Notebook widget."""
class tqdm . auto . tqdm ( tqdm . tqdm ):
"""Automatically chooses beween `tqdm.notebook` and `tqdm.tqdm`."""
class tqdm . asyncio . tqdm ( tqdm . tqdm ):
"""Asynchronous version."""
@ classmethod
def as_completed ( cls , fs , * , loop = None , timeout = None , total = None ,
** tqdm_kwargs ):
"""Wrapper for `asyncio.as_completed`."""
class tqdm . gui . tqdm ( tqdm . tqdm ):
"""Matplotlib GUI version."""
class tqdm . tk . tqdm ( tqdm . tqdm ):
"""Tkinter GUI version."""
class tqdm . rich . tqdm ( tqdm . tqdm ):
"""`rich.progress` version."""
class tqdm . keras . TqdmCallback ( keras . callbacks . Callback ):
"""Keras callback for epoch and batch progress."""
class tqdm . dask . TqdmCallback ( dask . callbacks . Callback ):
"""Dask callback for task progress."""
contrib
tqdm.contrib
パッケージには実験的なモジュールも含まれています。
tqdm.contrib.itertools
: itertools
の薄いラッパーtqdm.contrib.concurrent
: concurrent.futures
の薄いラッパーtqdm.contrib.slack
: Slack ボットへの投稿tqdm.contrib.discord
: Discord ボットへの投稿tqdm.contrib.telegram
: Telegram ボットへの投稿tqdm.contrib.bells
: すべてのオプション機能を自動的に有効にしますauto
、 pandas
、 slack
、 discord
、 telegram
help()
を実行します。カスタム情報は、 desc
引数とpostfix
引数を使用してtqdm
バーに動的に表示および更新できます。
from tqdm import tqdm , trange
from random import random , randint
from time import sleep
with trange ( 10 ) as t :
for i in t :
# Description will be displayed on the left
t . set_description ( 'GEN %i' % i )
# Postfix will be displayed on the right,
# formatted automatically based on argument's datatype
t . set_postfix ( loss = random (), gen = randint ( 1 , 999 ), str = 'h' ,
lst = [ 1 , 2 ])
sleep ( 0.1 )
with tqdm ( total = 10 , bar_format = "{postfix[0]} {postfix[1][value]:>8.2g}" ,
postfix = [ "Batch" , { "value" : 0 }]) as t :
for i in range ( 10 ):
sleep ( 0.1 )
t . postfix [ 1 ][ "value" ] = i / 2
t . update ()
bar_format
文字列で{postfix[...]}
使用する場合の注意点:
postfix
も互換性のある形式で初期引数として渡す必要があります。postfix
がdict
のようなオブジェクトの場合、文字列に自動変換されます。この動作を防ぐには、キーが文字列ではない追加の項目を辞書に挿入します。追加のbar_format
パラメータは、 format_dict
オーバーライドすることによって定義することもでき、バー自体はascii
使用して変更することもできます。
from tqdm import tqdm
class TqdmExtraFormat ( tqdm ):
"""Provides a `total_time` format parameter"""
@ property
def format_dict ( self ):
d = super (). format_dict
total_time = d [ "elapsed" ] * ( d [ "total" ] or 0 ) / max ( d [ "n" ], 1 )
d . update ( total_time = self . format_interval ( total_time ) + " in total" )
return d
for i in TqdmExtraFormat (
range (