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]
오버헤드는 반복당 약 60ns( tqdm.gui
의 경우 80ns)로 낮으며 성능 회귀에 대해 단위 테스트를 거쳤습니다. 이에 비해 잘 확립된 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의 릴리스: , 위키 또는 웹사이트에서 확인할 수 있습니다.
tqdm
은 매우 다재다능하며 다양한 방법으로 사용될 수 있습니다. 세 가지 주요 내용은 다음과 같습니다.
모든 반복 가능 항목 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]
가장 일반적인 문제는 깔끔한 한 줄 진행률 표시줄 대신 여러 줄의 과도한 출력과 관련이 있습니다.
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인 경우 유니코드(부드러운 블록)를 사용하여 미터를 채웁니다. 대체 방법은 ASCII 문자 " 123456789#"을 사용하는 것입니다.
전체 진행률 표시줄 래퍼를 비활성화할지 여부 [기본값: False]. 없음으로 설정하면 TTY가 아닌 경우 비활성화됩니다.
각 반복의 단위를 정의하는 데 사용되는 문자열입니다. [기본값: it].
1 또는 True인 경우 반복 횟수가 자동으로 줄어들거나 크기가 조정되고 국제 단위계 표준을 따르는 미터법 접두어가 추가됩니다(킬로, 메가 등)[기본값: False]. 0이 아닌 다른 숫자가 있으면 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, 백분율, elapsed, elapsed_s, ncols , nrows, desc, 단위, 속도, rate_fmt, rate_noinv, rate_noinv_fmt, rate_inv, rate_inv_fmt, postfix, unit_divisor, 잔여, 잔여_s, eta. 후행 ":"은 {desc}가 비어 있는 경우 자동으로 제거됩니다.
초기 카운터 값입니다. 진행률 표시줄을 다시 시작할 때 유용합니다. [기본값: 0] float를 사용하는 경우 bar_format
에 {n:.3f}
또는 유사한 항목을 지정하거나 unit_scale
지정하는 것을 고려하세요.
이 막대를 인쇄하려면 라인 오프셋을 지정하십시오(0부터 시작). 지정하지 않으면 자동입니다. 한 번에 여러 개의 막대를 관리하는 데 유용합니다(예: 스레드에서).
*
, 선택 사항 막대 끝에 표시할 추가 통계를 지정합니다. 가능하면 set_postfix(**postfix)
호출합니다(dict).
[기본값: 1000], unit_scale
이 True가 아니면 무시됩니다.
바이트를 쓸지 여부입니다. If (기본값: False)는 유니코드를 작성합니다.
중간 출력(초기화, 반복 및 업데이트)을 위해 refresh
위해 전달됩니다.
화면 높이. 지정된 경우 이 경계 외부에 중첩된 막대를 숨깁니다. 지정하지 않으면 환경 높이를 사용하려고 시도합니다. 폴백은 20입니다.
막대 색상(예: '녹색', '#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
: 텔레그램 봇에 대한 게시물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 (