Pular para o conteúdo principal
InicioTutoriaisPython

Tqdm Python: Um guia com exemplos práticos

O tqdm é uma biblioteca Python que fornece uma barra de progresso rápida e extensível para loops e iteráveis, facilitando a visualização do progresso do seu código.
Actualizado 13 de set. de 2024  · 11 min leer

Você já se viu em uma situação em que um script Python de longa duração o fez pensar se algo estava acontecendo por trás da tela?

A incerteza sobre o progresso pode fazer com que você cancele uma execução quase completa ou espere infinitamente por uma execução de script já interrompida.

O tqdm Python aborda esse problema fornecendo indicadores de progresso para seus scripts.

Exemplo de barra de progresso tqdm

O que é tqdm?

Tqdm é uma biblioteca Python que fornece barras de progresso rápidas e extensíveis para loops e iteráveis. É uma maneira simples de acompanhar o avanço de tarefas que demandam muito tempo.

O nome da biblioteca significa "progresso" em árabe (taqadum, تقدّم), e é uma abreviação de "Eu amo muito você" em espanhol (te quiero demasiado).

O Tdqm rastreia o progresso e atualiza a exibição da barra de progresso contando as iterações, calculando o tempo decorrido e o tempo restante e visualizando o progresso geral no preenchimento da barra.

Ele usa algoritmos inteligentes para prever o tempo restante e ignora exibições de iteração desnecessárias para minimizar a sobrecarga. O uso do site tqdm oferece vários benefícios, inclusive:

  • Feedback visual: As barras de progresso permitem que os usuários vejam quanto de uma tarefa está concluída e estimem quanto tempo a parte restante pode levar.
  • Funciona em qualquer lugar: A biblioteca tqdm funciona em qualquer plataforma (Linux, Windows, Mac, FreeBSD, NetBSD, SunOS), em qualquer console ou em uma GUI.
  • Fácil integração: Tqdm integra-se perfeitamente com notebooks Jupyter, bibliotecas comuns como Pandase construções comuns do Python, como loops.
  • Personalização: Ele oferece várias opções para personalizar a aparência e o comportamento das barras de progresso, que serão abordadas mais adiante.
  • Desempenho: Embora pacotes semelhantes, como ProgressBar têm uma sobrecarga de 800 ns/iteração, a sobrecarga do tdqm de 60 ns/iterações é muito mais rápida.

Torne-se um engenheiro de dados

Desenvolva habilidades em Python para se tornar um engenheiro de dados profissional.

Comece a Usar Gratuitamente

Como instalar o Tqdm 

Como acontece com a maioria das bibliotecas Python, a maneira mais fácil de instalar o tqdm é usando o gerenciador de pacotes pip.

pip install tqdm

Tqdm: Exemplo simples

Para criar uma barra de progresso, envolvemos nosso iterável com a função tqdm() (que importamos do módulo tqdm ). Vamos dar uma olhada em um exemplo simples. A função time.sleep(0.01) serve como um espaço reservado para o código que deve ser executado em cada iteração.

from tqdm import tqdm
    for i in tqdm(range(1000)):
    time.sleep(0.01)
    # …

gif mostrando a conclusão da barra de progresso do código de exemplo em 10 segundos.

Como atalho para tdqm(range(n)), você também pode usar trange(n). O código a seguir retornará exatamente o mesmo resultado que o anterior:

from tqdm import tqdm
    for i in trange(1000):
	time.sleep(0.01)
	# …

Ambos os exemplos retornarão uma barra de progresso parecida com a mostrada acima.

Dê uma olhada mais de perto na barra de progresso para ver quais informações ela fornece. Vamos analisar os detalhes apresentados por tqdm:

  • Indicadores de progresso:
    • Porcentagem de iterações
    • Preenchimento de barra
    • Fração do total de iterações
  • Métricas:
    • Tempo decorrido
    • Tempo restante estimado
    • Desempenho (iterações por segundo)

Personalização do Tqdm: Fazendo barras de progresso por conta própria

Tqdm oferece várias opções de personalização para que você possa ajustar a aparência e o comportamento das barras de progresso. Vamos dar uma olhada nos parâmetros de personalização mais importantes antes de examinar os casos de uso mais avançados do tqdm.

Adição de uma descrição da barra de progresso

Uma personalização comum é adicionar um rótulo descritivo usando o parâmetro desc, tornando a barra de progresso mais informativa e ajudando a manter uma visão geral dos diferentes iteráveis.

Por exemplo, se você adicionar o parâmetro desc=”Processing large range”, será exibido o título "Processing large range" (Processando intervalo grande) à esquerda da barra de progresso.

for _ in tqdm(range(20000000), desc="Processing large range"):
	continue

Recomendo que você execute o código acima em seu ambiente com e sem o parâmetro desc e observe as diferenças.

Especificar o número total de iterações

O parâmetro total especifica o número total de iterações no loop, permitindo que o tqdm forneça estimativas mais precisas do tempo restante e da porcentagem de conclusão.

Em um exemplo básico usando tqdm(range()) ou trange(), isso não é necessário, pois o número de iterações já está incluído nos colchetes. No entanto, há dois cenários principais em que a adição do parâmetro total=n (com n sendo o número total) pode ser útil: 

1. Iteráveis sem um método len(): Para iteráveis sem um método len(), como geradores com um número desconhecido de itens, você precisa fornecer o valor total manualmente. Sem esse parâmetro, o site tqdm() mostrará apenas a contagem de iterações concluídas. Observe que a barra de progresso começará novamente se o número real de itens ultrapassar o número total especificado.

from tqdm import tqdm
import time
import random
 
# Function generating random number between 1 and 100
def generate_random_numbers():
	while True:
	        yield random.randint(1, 100)
 
# Without total: tqdm() only shows number of iterations, does not know total
for num in tqdm(generate_random_numbers(), desc=’Random Iteration’):
	time.sleep(0.01)
	# …

Esse gif mostra a contagem de iterações sem uma barra de progresso.

É assim que você verá se o número de itens for desconhecido e não especificarmos o total.

# With total (assuming you know the desired number of iterations): tqdm() shows progress
num_iterations = 1000
for num in tqdm(generate_random_numbers(), total=num_iterations, desc="Random Iteration"):
	time.sleep(0.01)
	# …

Nesse gif, a barra de progresso fica visível novamente, depois que o parâmetro total é especificado.

Muito melhor, agora a barra de progresso é exibida!

2. Atualizações manuais: Se estivermos atualizando a barra de progresso manualmente em uma função usando o método update(), o valor total precisará ser especificado para garantir o acompanhamento correto do progresso. O método update() permite, por exemplo, responder a processos que mudam dinamicamente ou implementar um controle de progresso personalizado. Falaremos sobre isso mais tarde.

Ajuste da aparência visual

Se você quiser ajustar a ordem de posicionamento na qual os elementos da barra de progresso são exibidos, poderá definir o parâmetro bar_format como a string de formato preferida. Dessa forma, podemos controlar o posicionamento de vários elementos, como a porcentagem, o tempo decorrido e o caractere de preenchimento da barra. Para obter mais detalhes, você pode consultar a documentação.

Outro ajuste da aparência visual pode ser feito usando o parâmetro colour. É possível usar cadeias de palavras como "verde" ou cadeias de códigos hexadecimais como "#00ff00".

O parâmetro leave trata do desaparecimento e não da aparência: ele determina se a barra de progresso permanecerá visível ou não após a conclusão. Se você definir True, a barra persistirá após o término do loop; se definir False, ela desaparecerá.

Vamos dar uma olhada nas diferenças visuais dos resultados em outro exemplo. O código a seguir cria três barras de progresso: uma com configurações padrão, uma em que a ordem e a cor do elemento são alteradas e uma que é definida para desaparecer após a conclusão. Os resultados são visíveis no GIF abaixo.

from tqdm import tqdm
import time
 
# Progress bar 1: Default settings
for i in tqdm(range(300)):
	time.sleep(0.01)
 
# Progress bar 2: Customized bar format and color
for i in tqdm(range(300), bar_format='[{elapsed}<{remaining}] {n_fmt}/{total_fmt} | {l_bar}{bar} {rate_fmt}{postfix}', colour='yellow'):
	time.sleep(0.01)
 
# Progress bar 3: Customized bar format and color, leave=False
for i in tqdm(range(300), bar_format='[{elapsed}<{remaining}] {n_fmt}/{total_fmt} | {l_bar}{bar} {rate_fmt}{postfix}', colour='red', leave=False):
	time.sleep(0.01)

Um gif que mostra três barras de progresso diferentes: 1) Barra de progresso básica com configurações padrão, 2) barra de progresso amarela com tempo decorrido e estimativas de tempo à esquerda da porcentagem de conclusão e da barra de progresso, 3) versão vermelha da segunda barra que desaparece após a conclusão.

Uso avançado: Lidando com cenários mais complexos

Agora que sabemos como criar uma barra de progresso simples e como personalizá-la, podemos avançar para alguns casos mais avançados.

Barras de progresso aninhadas

Os loops aninhados são loops que estão contidos em outros loops. Dessa forma, as barras de progresso aninhadas são uma série de barras de progresso para cada iteração de loops contidos em outros loops. Para criá-los, envolva cada loop com uma função tqdm() e adicione rótulos descritivos para cada iterável. 

O código a seguir tem três loops aninhados e é capaz de dar um exemplo de como as barras de progresso aninhadas aparecerão:

from tqdm import trange
import time
 
for i in trange(3, desc='outer loop'):
	for j in trange(2, desc='middle loop'):
   		for k in trange(6, desc='inner loop'):
	time.sleep(0.01)

Uma captura de tela mostrando três barras de progresso aninhadas em um Jupyter Notebook. A barra de progresso mais externa rastreia o loop externo, a barra de progresso do meio rastreia o loop do meio e a barra de progresso mais interna rastreia o loop interno. Cada barra de progresso exibe a iteração atual, o total de iterações, o tempo restante estimado e uma barra de porcentagem de conclusão. A ordem das barras é a descrita no texto.

Na saída final acima, podemos reconhecer um padrão no qual as diferentes barras de progresso são atualizadas. O Tqdm sempre começará com o loop mais externo até chegar ao loop mais interno, cujas iterações serão processadas e a barra de progresso será atualizada de acordo.

Agora, digamos que você tenha três loops aninhados, como no exemplo. Após a iteração interna inicial, ele passará para o loop intermediário, atualizará como tendo uma iteração concluída, antes de voltar para o iterável interno. Esse processo é repetido até que o loop do meio seja marcado como concluído, o que fará com que a barra externa apareça com uma iteração concluída.

O mesmo acontece entre o loop externo e o médio. No final, a execução interna final conclui o iterável intermediário, que, por sua vez, conclui a última iteração externa.

Atualizações manuais

A atualização manual das barras de progresso com tqdm pode ser útil em vários cenários:

  • Iteráveis com comprimento desconhecido: Quando estamos trabalhando com iteráveis que não têm um comprimento definido (por exemplo, geradores, fluxos de rede), podemos atualizar manualmente a barra de progresso com base na quantidade de dados processados ou no número de operações concluídas.
  • Processos que mudam dinamicamente: Se o número de iterações ou o tempo de processamento por iteração puder mudar durante a execução, as atualizações manuais nos permitirão ajustar a barra de progresso de acordo.
  • Acompanhamento personalizado do progresso: Para obter um controle mais detalhado sobre a barra de progresso, podemos atualizá-la manualmente com base em critérios ou eventos específicos. Por exemplo, talvez você queira atualizar a barra de progresso com base na conclusão de determinados marcos ou no progresso de tarefas individuais em um processo maior.
  • Integração com sistemas externos: Se estivermos integrando o tqdm com sistemas externos ou bibliotecas que não oferecem uma maneira natural de acompanhar o progresso, as atualizações manuais poderão ser usadas para sincronizar a barra de progresso com o processo externo.

Para atualizar manualmente uma barra de progresso do tqdm, é importante que o parâmetro total seja especificado como a estimativa do número máximo esperado de iterações. Em seguida, à medida que o código processa cada novo elemento, a barra de progresso precisa ser atualizada usando o método update(). O valor de atualização deve representar o número de iterações processadas desde a última atualização.

Digamos que esperamos que nosso iterável contenha até 750 elementos. Neste exemplo, o comprimento real é um número aleatório entre 100 e 1.000, que é desconhecido para nós. Iniciamos o progress_bar, configurando estimated_total para 750. Em seguida, iteramos pelos dados, atualizando a barra de progresso depois que cada ponto é processado.

from tqdm import tqdm
def process_data(data):
	time.sleep(0.01)        	# simulate processing data
	processed_data = data
	return processed_data
# Generate an iterable with random length between 100 and 1,000
random_length = random.randint(100, 1000)
data_list = [i for i in range(random_length)]
# Define estimated maximum number of iterations
estimated_total = 750 
# Define the progress bar using the estimated_total
progress_bar = tqdm(total=estimated_total)
# Iterating through data list of unknown length
for data in data_list:
	processed_data = process_data(data)
	progress_bar.update(1)

Nesse gif, a barra de progresso é concluída em 100% (750/750) e, em seguida, continua a contar as iterações restantes (950 no final).

Subestimamos o comprimento do iterável, fazendo com que a saída continuasse contando as iterações depois de atingir 100% de progresso.

Multiprocessamento

O multiprocessamento e o encadeamento são técnicas usadas para executar tarefas simultaneamente, melhorando o desempenho e a capacidade de resposta. Nesses cenários, pode ser um desafio acompanhar o progresso de tarefas individuais ou o progresso geral da execução paralela. O site Tqdm pode ser uma ferramenta valiosa para fornecer feedback visual e monitorar o progresso dessas operações simultâneas.

O módulo tqdm.contrib.concurrent oferece funções especializadas para a criação de barras de progresso em contextos de multiprocessamento ou encadeamento. Essas funções lidam com a sincronização e a comunicação entre o processo principal e os processos ou threads de trabalho, garantindo que a barra de progresso seja atualizada corretamente. Eles foram projetados para funcionar perfeitamente com a API concurrent.futures, usando a função ProcessPoolExecutor() ou ThreadPoolExecutor().

Aqui está um exemplo usando o módulo tqdm.contrib.concurrent.futures:

import concurrent.futures
from tqdm.contrib.concurrent import process_map
 
def process_data(data):
	for i in tqdm(range(100), desc=f"Processing {data['name']}"):
	    	# Process data
	    	time.sleep(0.01)
 
if __name__ == '__main__':
	with concurrent.futures.ProcessPoolExecutor() as executor:
	    	results = process_map(process_data, [
	        	{'name': 'dataset1'},
	        	{'name': 'dataset2'},
	# …
	])

Neste exemplo, a função process_data() inclui uma barra de progresso tqdm para acompanhar seu progresso. A função process_data() será executada simultaneamente para cada item de dados da lista. Isso significa que várias barras de progresso serão exibidas simultaneamente, cada uma representando o progresso de um processo separado. O parâmetro desc é definido para criar dinamicamente uma descrição para cada barra de progresso com base no nome do conjunto de dados correspondente, o que nos ajuda a distinguir entre diferentes barras de progresso.

Integração com o pandas

O módulo tqdm.pandas oferece uma maneira conveniente de adicionar barras de progresso às operações do pandas. Isso é particularmente útil para operações demoradas em grandes DataFramespois fornece feedback visual sobre o andamento da tarefa. Você pode aplicar o decorador tqdm.pandas() a qualquer função pandas que opere em linhas ou colunas.

Para começar, definimos um DataFrame aleatório com 100.000 linhas e chamamos o decorador tqdm.pandas(). Se você quiser personalizar a barra de progresso, agora é o momento de fazê-lo, pois as funções progress_apply() e progress_map() não aceitam os parâmetros tqdm(). Aqui, queremos dar um nome às seguintes barras de progresso, portanto, também especificamos o parâmetro desc.

import pandas as pd
import numpy as np
from tqdm import tqdm
 
df = pd.DataFrame(np.random.randint(0, 10, (100000, 6)))
 
tqdm.pandas(desc='DataFrame Operation')

Agora você pode aplicar funções a linhas, colunas ou a todo o DataFrame. Em vez de usar uma das funções apply() ou map(), chame progress_apply() ou progress_map(), e a barra de progresso será exibida. Lembre-se de que apply() e progress_apply() podem ser aplicados a DataFrames, linhas ou colunas, enquanto map() e progress_map() só podem ser aplicados a séries ou colunas. Por exemplo:

# Halving each value in the DataFrame using progress_apply()
Result_apply = df.progress_apply(lambda x: x / 2)
 
# Doubling each element of the first column using progress_map()
result_map = df[0].progress_map(lambda x: x * 2)

Tqdm: Problemas comuns e correções

Vamos discutir alguns problemas e erros comuns do Tqdm e saber como corrigi-los.

A barra de progresso não está sendo atualizada

Um dos problemas mais comuns encontrados ao usar o site tqdm é uma barra de progresso não atualizada. Isso geralmente ocorre devido a problemas de buffer, especialmente em ambientes como o notebooks Jupyter. Quando a saída é armazenada em buffer, a barra de progresso pode não ser exibida ou atualizada imediatamente, levando à percepção de um processo congelado ou sem resposta.

O uso do módulo tqdm.notebook pode resolver problemas de buffer e garantir que a barra de progresso seja atualizada corretamente nos Jupyter Notebooks. Esse módulo fornece uma barra de progresso baseada em GUI, projetada especificamente para ambientes Jupyter.

Além disso, ele oferece dicas de cores fáceis de usar (azul: normal, verde: concluído, vermelho: erro/interrupção).

Se interrompermos o código do nosso exemplo de barra de progresso aninhada, ele terá a seguinte aparência:

Uma captura de tela que mostra a execução interrompida de três barras de progresso aninhadas em um Jupyter Notebook. Todas as barras concluídas estão na cor verde, enquanto as interrompidas estão na cor vermelha.

Barras de progresso aninhadas em Python usando tqdm.notebook, ilustrando o esquema de cores das barras concluídas e interrompidas.

Outra maneira eficaz de solucionar problemas de barras de progresso não atualizadas é liberar explicitamente o fluxo de saída. Quando os dados são gravados no fluxo de saída padrão (por exemplo, usando print()), eles geralmente são armazenados em buffer antes de serem enviados ao dispositivo de saída real. A liberação do fluxo de saída força o interpretador Python a enviar imediatamente todos os dados armazenados em buffer para o dispositivo de saída, garantindo que os dados sejam exibidos ou gravados sem atraso. 

Para liberar a saída, use o método flush() do fluxo de saída padrão. Para obter uma saída mais responsiva, considere a possibilidade de liberar o fluxo de saída com mais frequência, talvez a cada poucas iterações ou após um determinado período de tempo. Lembre-se de que há uma compensação, pois a descarga do fluxo de saída pode introduzir uma sobrecarga adicional. Aqui está um exemplo de como você pode incorporar o método em um processo simples do tqdm:

import sys
import time
from tqdm import tqdm
 
for i in tqdm(range(100)):
	time.sleep(0.1)
	sys.stdout.flush()  # Flush the output stream after each iteration

Problemas de compatibilidade

Embora o tqdm seja geralmente compatível com a maioria dos ambientes e bibliotecas Python, pode haver problemas ocasionais de compatibilidade ou comportamentos inesperados. Alguns cenários comuns dos quais você deve estar ciente incluem:

  • Fluxos de saída personalizados: Ao usar fluxos de saída personalizados ou redirecionar a saída para arquivos, o site tqdm pode não funcionar como esperado. Precisamos garantir que o fluxo de saída que estamos usando seja compatível com as operações necessárias para exibir a barra de progresso.
  • Bibliotecas de terceiros: Em alguns casos, o site tqdm pode interagir inesperadamente com bibliotecas de terceiros, especialmente aquelas que lidam com a saída ou com o acompanhamento do progresso. Podemos tentar desativar ou modificar os recursos relevantes da biblioteca de terceiros para ver se isso resolve o problema.
  • Compatibilidade com a versão: É sempre uma boa prática usar versões compatíveis do tqdm e de outras bibliotecas. Verifique a documentação da biblioteca para verificar se há problemas de compatibilidade conhecidos com versões específicas do Python ou outras dependências.

Ao encontrar problemas de compatibilidade, podemos considerar as seguintes soluções alternativas:

  • Fazer downgrade ou upgrade: Podemos tentar uma versão diferente de tqdm.
  • Modificar o código: Se necessário, podemos fazer ajustes em nosso código para contornar quaisquer conflitos de compatibilidade.
  • Procure ajuda da comunidade: Se tudo isso não ajudar, você pode entrar em contato com a comunidade tqdm ou com fóruns on-line para obter assistência e possíveis soluções.

Tendo em mente esses possíveis problemas de compatibilidade e suas soluções alternativas, podemos solucionar e resolver com eficácia quaisquer problemas encontrados ao usar o tqdm em nossos projetos Python.

Conclusão

Concluindo, o Tqdm é uma biblioteca Python que nos fornece barras de progresso e outras estatísticas úteis, facilitando o monitoramento e o gerenciamento da execução do código.

Se você estiver iterando em grandes conjuntos de dados, treinando modelos de aprendizado de máquinaou realizando qualquer outra operação demorada, o tqdm oferece uma maneira simples, porém eficiente, de acompanhar o progresso e manter-se informado sobre o status do seu código.

Para explorar mais, você pode conferir os outros tutoriais de Python do DataCampe a documentação do Tqdmou seu código-fonte e o Readme no GitHub.

Perguntas frequentes

Como faço para criar uma barra de progresso simples com o tqdm?

Instale e importe a biblioteca tqdm e, em seguida, envolva seu iterável com a função tqdm().

Posso usar o tqdm com DataFrames do pandas ou outras bibliotecas?

Sim, você pode usar tqdm com pandas DataFrames e outras bibliotecas. O módulo tqdm.pandas fornece funções específicas para a integração do tqdm com o pandas.

Posso personalizar a aparência da barra de progresso do Tqdm?

Sim, você pode personalizar o formato da barra, a cor, o número total de iterações e muito mais usando os parâmetros do Tqdm.

A barra de progresso do Tqdm não está sendo atualizada corretamente, o que devo fazer?

Verifique se há problemas de buffer, especialmente nos Jupyter Notebooks. Tente usar tqdm.notebook ou liberar explicitamente a saída. Além disso, garanta o uso correto do parâmetro total.


Photo of Tom Farnschläder
Author
Tom Farnschläder
LinkedIn

Depois de construir uma base sólida em economia, direito e contabilidade em meus estudos duplos na administração financeira regional, entrei em contato com a estatística pela primeira vez em meus estudos de ciências sociais e no trabalho como tutor. Ao realizar análises empíricas quantitativas, descobri uma paixão que me levou a continuar minha jornada no belo campo da ciência de dados e a aprender ferramentas de análise como R, SQL e Python. Atualmente, estou aprimorando minhas habilidades práticas na Deutsche Telekom, onde posso receber muita experiência prática na codificação de caminhos de dados para importar, processar e analisar dados usando Python.

Temas

Os melhores cursos de Python!

Certificação disponível

Course

Introdução ao Python para desenvolvedores

3 hr
20.9K
Domine os fundamentos da programação em Python. Você não precisa de conhecimento prévio!
See DetailsRight Arrow
Start Course
Ver maisRight Arrow