tqdm
deriva de la palabra árabe taqaddum (تقدّم) que puede significar "progreso" y es una abreviatura de "te quiero mucho" en español ( te quiero demasiado ).
Haga que sus bucles muestren instantáneamente un medidor de progreso inteligente: simplemente ajuste cualquier iterable con tqdm(iterable)
y ¡listo!
from tqdm import tqdm
for i in tqdm ( range ( 10000 )):
...
76%|████████████████████████ | 7568/10000 [00:33<00:10, 229.00it/s]
trange(N)
también se puede utilizar como un atajo conveniente para tqdm(range(N))
.
También se puede ejecutar como módulo con tuberías:
$ 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]
Los gastos generales son bajos: alrededor de 60 ns por iteración (80 ns con tqdm.gui
) y se prueban unitariamente contra la regresión de rendimiento. En comparación, el bien establecido ProgressBar tiene una sobrecarga de 800 ns/iter.
Además de su baja sobrecarga, tqdm
utiliza algoritmos inteligentes para predecir el tiempo restante y omitir visualizaciones de iteraciones innecesarias, lo que permite una sobrecarga insignificante en la mayoría de los casos.
tqdm
funciona en cualquier plataforma (Linux, Windows, Mac, FreeBSD, NetBSD, Solaris/SunOS), en cualquier consola o en una GUI, y también es compatible con portátiles IPython/Jupyter.
tqdm
no requiere ninguna dependencia (¡ni siquiera curses
!), solo Python y un entorno que admita carriage return r
y line feed n
caracteres de control.
Tabla de contenido
contrib
asyncio
logging
pip install tqdm
Extraiga e instale la rama devel
previa al lanzamiento:
pip install " git+https://github.com/tqdm/tqdm.git@devel#egg=tqdm "
conda install -c conda-forge tqdm
Hay 3 canales para elegir:
snap install tqdm # implies --stable, i.e. latest tagged release
snap install tqdm --candidate # master branch
snap install tqdm --edge # devel branch
Tenga en cuenta que los archivos binarios snap
son exclusivamente para uso CLI (no se pueden import
) y configuran automáticamente la finalización de pestañas bash
.
docker pull tqdm/tqdm
docker run -i --rm tqdm/tqdm --help
Hay otros lugares (no oficiales) donde se puede descargar tqdm
, particularmente para uso CLI:
La lista de todos los cambios está disponible en las Versiones de GitHub: , en la wiki o en el sitio web.
tqdm
es muy versátil y se puede utilizar de varias maneras. Los tres principales se detallan a continuación.
Envuelva tqdm()
alrededor de cualquier iterable:
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)
es una instancia optimizada especial de tqdm(range(i))
:
from tqdm import trange
for i in trange ( 100 ):
sleep ( 0.01 )
La creación de instancias fuera del bucle permite el control manual sobre tqdm()
:
pbar = tqdm ([ "a" , "b" , "c" , "d" ])
for char in pbar :
sleep ( 0.25 )
pbar . set_description ( "Processing %s" % char )
Control manual de actualizaciones de tqdm()
usando una declaración with
:
with tqdm ( total = 100 ) as pbar :
for i in range ( 10 ):
sleep ( 0.1 )
pbar . update ( 10 )
Si se proporciona la variable opcional total
(o un iterable con len()
), se muestran estadísticas predictivas.
with
también es opcional (puedes simplemente asignar tqdm()
a una variable, pero en este caso no olvides del
o close()
al final:
pbar = tqdm ( total = 100 )
for i in range ( 10 ):
sleep ( 0.1 )
pbar . update ( 10 )
pbar . close ()
Quizás el uso más maravilloso de tqdm
sea en un script o en la línea de comando. Simplemente insertando tqdm
(o python -m tqdm
) entre las tuberías pasará por todas stdin
a stdout
mientras se imprime el progreso en stderr
.
El siguiente ejemplo demuestra cómo contar el número de líneas en todos los archivos Python en el directorio actual, con información de tiempo incluida.
$ 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
Tenga en cuenta que también se pueden especificar los argumentos habituales para 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]
¿Hacer una copia de seguridad de un directorio grande?
$ tar -zcf - docs/ | tqdm --bytes --total ` du -sb docs/ | cut -f1 `
> backup.tgz
44% | ██████████████▊ | 153M/352M [00: 14< 00:18, 11.0MB/s]
Esto se puede embellecer aún má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]
O hacerlo a nivel de archivo usando 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]
Los programas CLI preexistentes que ya generan información de progreso básica se beneficiarán de los indicadores --update
y --update_to
de 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]
Los problemas más comunes se relacionan con una producción excesiva en varias líneas, en lugar de una barra de progreso ordenada de una sola línea.
CR
, r
).r
correctamente (cloudwatch, K8s) pueden beneficiarse de export TQDM_POSITION=-1
.colorama
del módulo Python para garantizar que las barras anidadas permanezcan dentro de sus respectivas líneas.ascii
.tqdm
no lo hace.tqdm(enumerate(...))
con enumerate(tqdm(...))
o tqdm(enumerate(x), total=len(x), ...)
. Lo mismo se aplica a numpy.ndenumerate
.tqdm(zip(a, b))
con zip(tqdm(a), b)
o incluso zip(tqdm(a), tqdm(b))
.itertools
.tqdm.contrib
.docker-compose run
en lugar de docker-compose up
y tty: true
.export TQDM_MININTERVAL=5
para evitar registros no deseados. Esta lógica de anulación es manejada por el decorador tqdm.utils.envwrap
(útil independiente de tqdm
).Si encuentra otras dificultades, navegue y archive.
(Desde el 19 de mayo de 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 ):
Iterable para decorar con una barra de progreso. Déjelo en blanco para administrar manualmente las actualizaciones.
Prefijo para la barra de progreso.
El número de iteraciones esperadas. Si no se especifica, se utiliza len(iterable) si es posible. Si es flotante("inf") o como último recurso, solo se muestran estadísticas de progreso básicas (sin ETA, sin barra de progreso). Si gui
es Verdadero y este parámetro necesita una actualización posterior, especifique un número inicial positivo grande y arbitrario, por ejemplo, 9e9.
Si [predeterminado: Verdadero], mantiene todos los rastros de la barra de progreso al finalizar la iteración. Si es None
, se irá sólo si position
es 0
.
io.TextIOWrapper
o io.StringIO
, opcional Especifica dónde generar los mensajes de progreso (predeterminado: sys.stderr). Utiliza los métodos file.write(str)
y file.flush()
. Para codificar, consulte write_bytes
.
El ancho de todo el mensaje de salida. Si se especifica, cambia dinámicamente el tamaño de la barra de progreso para permanecer dentro de este límite. Si no se especifica, intenta utilizar el ancho del entorno. El respaldo es un ancho de 10 metros y no hay límite para el contador y las estadísticas. Si es 0, no imprimirá ningún medidor (solo estadísticas).
Intervalo mínimo de actualización de la pantalla de progreso [predeterminado: 0,1] segundos.
Intervalo máximo de actualización de la pantalla de progreso [predeterminado: 10] segundos. Ajusta automáticamente miniters
para que correspondan al mininterval
después de un largo retraso en la actualización de la pantalla. Solo funciona si dynamic_miniters
o el subproceso de monitor están habilitados.
Intervalo mínimo de actualización de la visualización del progreso, en iteraciones. Si es 0 dynamic_miniters
, se ajustará automáticamente a mininterval
igual (más eficiente en la CPU, bueno para bucles cerrados). Si > 0, omitirá la visualización del número especificado de iteraciones. Modifique esto y mininterval
para obtener bucles muy eficientes. Si su progreso es errático con iteraciones rápidas y lentas (red, omisión de elementos, etc.), debe configurar miniters=1.
Si no se especifica o es falso, utilice Unicode (bloques suaves) para llenar el medidor. La alternativa es utilizar caracteres ASCII "123456789#".
Si se debe deshabilitar todo el contenedor de la barra de progreso [predeterminado: Falso]. Si se establece en Ninguno, desactívelo en no TTY.
Cadena que se utilizará para definir la unidad de cada iteración [predeterminado: it].
Si es 1 o Verdadero, el número de iteraciones se reducirá/escalará automáticamente y se agregará un prefijo métrico siguiendo el estándar del Sistema Internacional de Unidades (kilo, mega, etc.) [predeterminado: Falso]. Si es cualquier otro número distinto de cero, se escalará total
y n
.
Si se establece, altera constantemente ncols
y nrows
según el entorno (lo que permite cambiar el tamaño de las ventanas) [predeterminado: Falso].
Factor de suavizado de media móvil exponencial para estimaciones de velocidad (ignorado en el modo GUI). Varía de 0 (velocidad promedio) a 1 (velocidad actual/instantánea) [predeterminado: 0,3].
Especifique un formato de cadena de barra personalizado. Puede afectar el rendimiento. [predeterminado: '{l_bar}{bar}{r_bar}'], donde l_bar='{desc}: {porcentaje:3.0f}%|' y r_bar='| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, ' '{rate_fmt}{postfix}]' Posibles vars: l_bar, bar, r_bar, n, n_fmt, total, total_fmt, porcentaje, transcurrido, transcurrido_s, ncols , nrows, desc, unidad, tasa, rate_fmt, rate_noinv, rate_noinv_fmt, rate_inv, rate_inv_fmt, postfix, unit_divisor, restante, restante_s, eta. Tenga en cuenta que un ":" final se elimina automáticamente después de {desc} si este último está vacío.
El valor del contador inicial. Útil al reiniciar una barra de progreso [predeterminado: 0]. Si usa float, considere especificar {n:.3f}
o similar en bar_format
, o especificar unit_scale
.
Especifique el desplazamiento de línea para imprimir esta barra (a partir de 0). Automático si no se especifica. Útil para gestionar varias barras a la vez (por ejemplo, desde hilos).
*
, opcional Especifique estadísticas adicionales para mostrar al final de la barra. Llama set_postfix(**postfix)
si es posible (dict).
[predeterminado: 1000], ignorado a menos que unit_scale
sea True.
Ya sea para escribir bytes. Si (predeterminado: Falso) se escribirá Unicode.
Se pasó a refresh
para salida intermedia (inicialización, iteración y actualización).
La altura de la pantalla. Si se especifica, oculta las barras anidadas fuera de este límite. Si no se especifica, intenta utilizar la altura del entorno. La reserva es 20.
Color de la barra (por ejemplo, 'verde', '#00ff00').
No mostrar hasta que hayan transcurrido [predeterminado: 0] segundos.
delim
.delim
y establecerá de forma predeterminada unit_scale
en True, unit_divisor
en 1024 y unit
en 'B'.stdin
tanto a stderr
como stdout
.update()
. Tenga en cuenta que esto es lento (~2e5 it/s) ya que cada entrada debe decodificarse como un número.self.n
Tenga en cuenta que esto es lento (~2e5 it/s) ya que cada entrada debe decodificarse como un número. 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
El paquete tqdm.contrib
también contiene módulos experimentales:
tqdm.contrib.itertools
: Envoltorios finos alrededor de itertools
tqdm.contrib.concurrent
: Envoltorios finos alrededor de concurrent.futures
tqdm.contrib.slack
: Publicaciones en bots de Slacktqdm.contrib.discord
: Publicaciones en robots de Discordtqdm.contrib.telegram
: Publicaciones en bots de Telegramtqdm.contrib.bells
: habilita automáticamente todas las funciones opcionalesauto
, pandas
, slack
, discord
, telegram
help()
; La información personalizada se puede mostrar y actualizar dinámicamente en las barras tqdm
con los argumentos desc
y postfix
:
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 ()
Puntos para recordar al usar {postfix[...]}
en la cadena bar_format
:
postfix
también debe pasarse como argumento inicial en un formato compatible, ypostfix
se convertirá automáticamente en una cadena si es un objeto tipo dict
. Para evitar este comportamiento, inserte un elemento adicional en el diccionario donde la clave no sea una cadena. También se pueden definir parámetros bar_format
adicionales anulando format_dict
, y la barra misma se puede modificar usando 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 (