tqdm
leitet sich vom arabischen Wort taqaddum (تقدّم) ab, das „Fortschritt“ bedeuten kann und auf Spanisch eine Abkürzung für „Ich liebe dich so sehr“ ( te quiero demasiado ) ist.
Sorgen Sie dafür, dass Ihre Schleifen sofort eine intelligente Fortschrittsanzeige anzeigen – schließen Sie einfach alle Iterables mit tqdm(iterable)
ein, und schon sind Sie fertig!
from tqdm import tqdm
for i in tqdm ( range ( 10000 )):
...
76%|████████████████████████ | 7568/10000 [00:33<00:10, 229.00it/s]
trange(N)
kann auch als praktische Abkürzung für tqdm(range(N))
verwendet werden.
Es kann auch als Modul mit Pipes ausgeführt werden:
$ 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]
Der Overhead ist gering – etwa 60 ns pro Iteration (80 ns mit tqdm.gui
) und wird im Unit-Test gegen Leistungsregression getestet. Im Vergleich dazu hat die bewährte ProgressBar einen Overhead von 800 ns/Iter.
Zusätzlich zu seinem geringen Overhead verwendet tqdm
intelligente Algorithmen, um die verbleibende Zeit vorherzusagen und unnötige Iterationsanzeigen zu überspringen, was in den meisten Fällen einen vernachlässigbaren Overhead ermöglicht.
tqdm
funktioniert auf jeder Plattform (Linux, Windows, Mac, FreeBSD, NetBSD, Solaris/SunOS), in jeder Konsole oder in einer GUI und ist auch mit IPython/Jupyter-Notebooks kompatibel.
tqdm
erfordert keine Abhängigkeiten (nicht einmal curses
!), nur Python und eine Umgebung, die die Steuerzeichen carriage return r
und line feed n
unterstützt.
Inhaltsverzeichnis
contrib
asyncio
logging
umleitenpip install tqdm
Ziehen Sie den Vorabversions- devel
herunter und installieren Sie ihn:
pip install " git+https://github.com/tqdm/tqdm.git@devel#egg=tqdm "
conda install -c conda-forge tqdm
Es stehen 3 Kanäle zur Auswahl:
snap install tqdm # implies --stable, i.e. latest tagged release
snap install tqdm --candidate # master branch
snap install tqdm --edge # devel branch
Beachten Sie, dass snap
Binärdateien ausschließlich zur CLI-Verwendung dienen (nicht import
sind) und automatisch bash
Tab-Vervollständigung einrichten.
docker pull tqdm/tqdm
docker run -i --rm tqdm/tqdm --help
Es gibt andere (inoffizielle) Orte, an denen tqdm
heruntergeladen werden kann, insbesondere für die CLI-Nutzung:
Die Liste aller Änderungen ist entweder auf GitHubs Releases: , im Wiki oder auf der Website verfügbar.
tqdm
ist sehr vielseitig und vielfältig einsetzbar. Die drei wichtigsten sind unten aufgeführt.
Wickeln Sie tqdm()
um jedes iterierbare Element:
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)
ist eine speziell optimierte Instanz von tqdm(range(i))
:
from tqdm import trange
for i in trange ( 100 ):
sleep ( 0.01 )
Die Instanziierung außerhalb der Schleife ermöglicht die manuelle Steuerung von tqdm()
:
pbar = tqdm ([ "a" , "b" , "c" , "d" ])
for char in pbar :
sleep ( 0.25 )
pbar . set_description ( "Processing %s" % char )
Manuelle Steuerung von tqdm()
-Updates mithilfe einer with
-Anweisung:
with tqdm ( total = 100 ) as pbar :
for i in range ( 10 ):
sleep ( 0.1 )
pbar . update ( 10 )
Wenn die optionale Variable total
(oder eine Iterable mit len()
) bereitgestellt wird, werden Vorhersagestatistiken angezeigt.
with
ist ebenfalls optional (Sie können tqdm()
einfach einer Variablen zuweisen, aber vergessen Sie in diesem Fall nicht, am Ende del
oder close()
einzugeben:
pbar = tqdm ( total = 100 )
for i in range ( 10 ):
sleep ( 0.1 )
pbar . update ( 10 )
pbar . close ()
Die vielleicht wunderbarste Verwendung von tqdm
ist in einem Skript oder in der Befehlszeile. Durch einfaches Einfügen von tqdm
(oder python -m tqdm
) zwischen den Pipes werden alle stdin
nach stdout
weitergeleitet, während der Fortschritt nach stderr
gedruckt wird.
Das folgende Beispiel zeigt, wie die Anzahl der Zeilen in allen Python-Dateien im aktuellen Verzeichnis gezählt wird, einschließlich Zeitinformationen.
$ 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
Beachten Sie, dass auch die üblichen Argumente für tqdm
angegeben werden können.
$ 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]
Ein großes Verzeichnis sichern?
$ tar -zcf - docs/ | tqdm --bytes --total ` du -sb docs/ | cut -f1 `
> backup.tgz
44% | ██████████████▊ | 153M/352M [00: 14< 00:18, 11.0MB/s]
Dies kann noch weiter verschönert werden:
$ 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]
Oder auf Dateiebene mit 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]
Bereits vorhandene CLI-Programme, die bereits grundlegende Fortschrittsinformationen ausgeben, profitieren von den Flags --update
und --update_to
von tqdm
:
$ 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]
Die häufigsten Probleme beziehen sich auf eine übermäßige Ausgabe in mehreren Zeilen anstelle eines übersichtlichen, einzeiligen Fortschrittsbalkens.
CR
, r
).r
nicht ordnungsgemäß unterstützen (Cloudwatch, K8s), können von export TQDM_POSITION=-1
profitieren.colorama
erforderlich, um sicherzustellen, dass verschachtelte Balken innerhalb ihrer jeweiligen Zeilen bleiben.ascii
-Leiste.tqdm
nicht.tqdm(enumerate(...))
durch enumerate(tqdm(...))
oder tqdm(enumerate(x), total=len(x), ...)
. Das Gleiche gilt für numpy.ndenumerate
.tqdm(zip(a, b))
durch zip(tqdm(a), b)
oder sogar zip(tqdm(a), tqdm(b))
.itertools
.tqdm.contrib
.docker-compose run
anstelle von docker-compose up
und tty: true
.export TQDM_MININTERVAL=5
um Protokoll-Spam zu vermeiden. Diese Überschreibungslogik wird vom Dekorator tqdm.utils.envwrap
verwaltet (nützlich unabhängig von tqdm
).Wenn Sie auf andere Schwierigkeiten stoßen, durchsuchen und archivieren.
(Seit 19. Mai 2016)
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 ):
Kann mit einem Fortschrittsbalken dekoriert werden. Lassen Sie das Feld leer, um die Updates manuell zu verwalten.
Präfix für den Fortschrittsbalken.
Die Anzahl der erwarteten Iterationen. Wenn nicht angegeben, wird nach Möglichkeit len(iterable) verwendet. Bei float("inf") oder als letzte Möglichkeit werden nur grundlegende Fortschrittsstatistiken angezeigt (keine ETA, kein Fortschrittsbalken). Wenn gui
True ist und dieser Parameter anschließend aktualisiert werden muss, geben Sie zunächst eine beliebige große positive Zahl an, z. B. 9e9.
Wenn [Standard: True], werden alle Spuren des Fortschrittsbalkens nach Beendigung der Iteration beibehalten. Wenn None
, wird es nur verlassen, wenn position
0
ist.
io.TextIOWrapper
oder io.StringIO
, optional Gibt an, wo die Fortschrittsmeldungen ausgegeben werden sollen (Standard: sys.stderr). Verwendet die Methoden file.write(str)
und file.flush()
. Informationen zur Codierung finden Sie unter write_bytes
.
Die Breite der gesamten Ausgabenachricht. Wenn angegeben, wird die Größe des Fortschrittsbalkens dynamisch angepasst, um innerhalb dieser Grenze zu bleiben. Wenn nicht angegeben, wird versucht, die Umgebungsbreite zu verwenden. Der Fallback ist eine Breite von 10 Metern und keine Begrenzung für Zähler und Statistiken. Wenn 0, wird kein Messgerät gedruckt (nur Statistiken).
Minimales Aktualisierungsintervall für die Fortschrittsanzeige [Standard: 0,1] Sekunden.
Maximales Aktualisierungsintervall für die Fortschrittsanzeige [Standard: 10] Sekunden. Passt miniters
nach einer langen Anzeigeaktualisierungsverzögerung automatisch an mininterval
an. Funktioniert nur, wenn dynamic_miniters
oder „Monitor-Thread“ aktiviert ist.
Minimales Aktualisierungsintervall für die Fortschrittsanzeige in Iterationen. Bei 0 und dynamic_miniters
wird automatisch das gleiche mininterval
eingestellt (CPU-effizienter, gut für enge Schleifen). Wenn > 0, wird die Anzeige der angegebenen Anzahl von Iterationen übersprungen. Optimieren Sie dies und mininterval
um sehr effiziente Schleifen zu erhalten. Wenn Ihr Fortschritt sowohl bei schnellen als auch bei langsamen Iterationen (Netzwerk, Überspringen von Elementen usw.) unregelmäßig ist, sollten Sie miniters=1 setzen.
Wenn nicht angegeben oder falsch, verwenden Sie Unicode (glatte Blöcke), um den Zähler zu füllen. Der Fallback besteht in der Verwendung der ASCII-Zeichen „123456789#“.
Ob der gesamte Fortschrittsbalken-Wrapper deaktiviert werden soll [Standard: False]. Wenn „Keine“ festgelegt ist, deaktivieren Sie diese Option bei Nicht-TTY.
Zeichenfolge, die zum Definieren der Einheit jeder Iteration verwendet wird [Standard: it].
Wenn 1 oder True, wird die Anzahl der Iterationen automatisch reduziert/skaliert und ein metrisches Präfix gemäß dem Standard des Internationalen Einheitensystems wird hinzugefügt (Kilo, Mega usw.) [Standard: False]. Wenn eine andere Zahl ungleich Null vorhanden ist, wird total
und n
skaliert.
Wenn festgelegt, werden ncols
und nrows
ständig an die Umgebung angepasst (wodurch Fenstergrößen geändert werden können) [Standard: False].
Exponentieller Glättungsfaktor des gleitenden Durchschnitts für Geschwindigkeitsschätzungen (wird im GUI-Modus ignoriert). Der Bereich reicht von 0 (Durchschnittsgeschwindigkeit) bis 1 (aktuelle/augenblickliche Geschwindigkeit) [Standard: 0,3].
Geben Sie eine benutzerdefinierte Formatierung für die Balkenzeichenfolge an. Kann die Leistung beeinträchtigen. [Standard: '{l_bar}{bar}{r_bar}'], wobei l_bar='{desc}: {percentage:3.0f}%|' und r_bar='| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, ' '{rate_fmt}{postfix}]' Mögliche Variablen: l_bar, bar, r_bar, n, n_fmt, total, total_fmt, Prozentsatz, verstrichen, verstrichene_s, ncols , nrows, absteigend, Einheit, Rate, rate_fmt, rate_noinv, rate_noinv_fmt, rate_inv, rate_inv_fmt, Postfix, Unit_divisor, verbleibend, verbleibende_s, eta. Beachten Sie, dass ein abschließendes „:“ nach {desc} automatisch entfernt wird, wenn letzteres leer ist.
Der anfängliche Zählerwert. Nützlich beim Neustart eines Fortschrittsbalkens [Standard: 0]. Wenn Sie float verwenden, sollten Sie in Betracht ziehen, {n:.3f}
oder ähnliches in bar_format
anzugeben oder unit_scale
anzugeben.
Geben Sie den Zeilenversatz zum Drucken dieses Balkens an (beginnend bei 0). Automatisch, wenn nicht angegeben. Nützlich, um mehrere Balken gleichzeitig zu verwalten (z. B. aus Threads).
*
, optional Geben Sie zusätzliche Statistiken an, die am Ende der Leiste angezeigt werden sollen. Ruft wenn möglich set_postfix(**postfix)
auf (dict).
[Standard: 1000], wird ignoriert, es sei denn, unit_scale
ist True.
Ob Bytes geschrieben werden sollen. Wenn (Standard: Falsch), wird Unicode geschrieben.
Wird zur refresh
übergeben (Initialisierung, Iteration und Aktualisierung).
Die Bildschirmhöhe. Wenn angegeben, werden verschachtelte Balken außerhalb dieser Grenze ausgeblendet. Wenn nicht angegeben, wird versucht, die Umgebungshöhe zu verwenden. Der Fallback beträgt 20.
Balkenfarbe (z. B. „grün“, „#00ff00“).
Wird erst angezeigt, wenn [Standard: 0] Sekunden vergangen sind.
delim
angegeben ist.delim
ignoriert und unit_scale
standardmäßig auf „True“, unit_divisor
auf „1024“ und unit
auf „B“ gesetzt.stdin
sowohl an stderr
als auch an stdout
übergeben.update()
übergeben werden. Beachten Sie, dass dies langsam ist (~2e5 it/s), da jede Eingabe als Zahl dekodiert werden muss.self.n
zugewiesen werden sollen. Beachten Sie, dass dies langsam ist (~2e5 it/s), da jede Eingabe als Zahl dekodiert werden muss. 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
Das Paket tqdm.contrib
enthält auch experimentelle Module:
tqdm.contrib.itertools
: Dünne Wrapper um itertools
tqdm.contrib.concurrent
: Dünne Wrapper um concurrent.futures
tqdm.contrib.slack
: Beiträge an Slack-Botstqdm.contrib.discord
: Beiträge zu Discord-Botstqdm.contrib.telegram
: Beiträge an Telegram-Botstqdm.contrib.bells
: Aktiviert automatisch alle optionalen Funktionenauto
, pandas
, slack
, discord
, telegram
help()
aus. Benutzerdefinierte Informationen können mit den Argumenten desc
und postfix
dynamisch auf tqdm
-Leisten angezeigt und aktualisiert werden:
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 ()
Beachten Sie Folgendes bei der Verwendung {postfix[...]}
im bar_format
-String:
postfix
muss auch als Anfangsargument in einem kompatiblen Format übergeben werden, undpostfix
wird automatisch in eine Zeichenfolge konvertiert, wenn es sich um ein dict
-ähnliches Objekt handelt. Um dieses Verhalten zu verhindern, fügen Sie ein zusätzliches Element in das Wörterbuch ein, bei dem der Schlüssel keine Zeichenfolge ist. Zusätzliche bar_format
-Parameter können auch durch Überschreiben von format_dict
definiert werden, und die Leiste selbst kann mit ascii
geändert werden:
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 (