tqdm dans Jupyter Notebook imprime de nouvelles barres de progression à plusieurs reprises

138

J'utilise tqdmpour imprimer la progression dans un script que j'exécute dans un bloc-notes Jupyter. J'imprime tous les messages sur la console via tqdm.write(). Cependant, cela me donne toujours une sortie biaisée comme ceci:

entrez la description de l'image ici

Autrement dit, chaque fois qu'une nouvelle ligne doit être imprimée, une nouvelle barre de progression est imprimée sur la ligne suivante. Cela ne se produit pas lorsque j'exécute le script via un terminal. Comment puis-je resoudre ceci?

Rohan Saxena
la source
En fait, quand j'utilise tqdm_notebook, je peux même faire des prints normales , et cela n'affecte pas la barre de progression.
Tomasz Gandor
une alternative est d'utiliser ce progressbar stackoverflow.com/questions/3160699/python-progress-bar
...

Réponses:

216

Essayez d'utiliser à la tqdm.notebook.tqdmplace de tqdm, comme indiqué ici .

Cela peut être aussi simple que de changer votre importation en:

from tqdm.notebook import tqdm

Bonne chance!

EDIT: Après les tests, il semble que cela tqdmfonctionne correctement en «mode texte» dans le bloc-notes Jupyter. C'est difficile à dire car vous n'avez pas fourni d' exemple minimal , mais il semble que votre problème soit causé par une instruction d'impression à chaque itération. L'instruction d'impression sort un nombre (~ 0,89) entre chaque mise à jour de la barre d'état, ce qui perturbe la sortie. Essayez de supprimer l'instruction d'impression.

Oscarbranson
la source
2
Je n'ai pas utilisé de print()déclaration, j'ai utilisé tqdm.write(). Cependant, tqdm_notebookdonne de bons résultats. Merci
:)
Savez-vous s'il prend en charge Python 3.6? Je n'ai pas eu de chance avec ça
Jon
1
Quelle erreur obtenez vous? Ça fonctionne bien pour moi. Impossible d'aider avec si peu d'informations ... Avez-vous activé ipywidgets dans jupyer ? Avez-vous simplement clair tqdm, plutôt que tqdm_notebook? Cela fonctionne bien avec Python 3.6 et Jupyter 1.0.0.
oscarbranson
tqdm_notebook de tqdm 4.19.4 fonctionne pour moi sur Python 3.6, Jupyter notebook 5.0.0 et ipywidgets 7.0.3.
Matt Kleinsmith du
2
@ bugmenot123 Bonne capture, corrigé.
Czyzby le
39

Ceci est une réponse alternative au cas où tqdm_notebook ne fonctionne pas pour vous.

Compte tenu de l'exemple suivant:

from time import sleep
from tqdm import tqdm

values = range(3)
with tqdm(total=len(values)) as pbar:
    for i in values:
        pbar.write('processed: %d' %i)
        pbar.update(1)
        sleep(1)

La sortie ressemblerait à quelque chose comme ceci (la progression apparaîtrait en rouge):

  0%|          | 0/3 [00:00<?, ?it/s]
processed: 1
 67%|██████▋   | 2/3 [00:01<00:00,  1.99it/s]
processed: 2
100%|██████████| 3/3 [00:02<00:00,  1.53it/s]
processed: 3

Le problème est que la sortie vers stdout et stderr est traitée de manière asynchrone et séparément en termes de nouvelles lignes.

Si, par exemple, Jupyter reçoit sur stderr la première ligne, puis la sortie "traitée" sur stdout. Ensuite, une fois qu'il reçoit une sortie sur stderr pour mettre à jour la progression, il ne reviendra pas et met à jour la première ligne car il ne mettra à jour que la dernière ligne. Au lieu de cela, il devra écrire une nouvelle ligne.

Solution de contournement 1, écriture sur stdout

Une solution de contournement serait de générer les deux vers stdout à la place:

import sys
from time import sleep
from tqdm import tqdm

values = range(3)
with tqdm(total=len(values), file=sys.stdout) as pbar:
    for i in values:
        pbar.write('processed: %d' % (1 + i))
        pbar.update(1)
        sleep(1)

La sortie passera à (plus de rouge):

processed: 1   | 0/3 [00:00<?, ?it/s]
processed: 2   | 0/3 [00:00<?, ?it/s]
processed: 3   | 2/3 [00:01<00:00,  1.99it/s]
100%|██████████| 3/3 [00:02<00:00,  1.53it/s]

Ici, nous pouvons voir que Jupyter ne semble pas s'éclaircir avant la fin de la ligne. Nous pourrions ajouter une autre solution de contournement pour cela en ajoutant des espaces. Tel que:

import sys
from time import sleep
from tqdm import tqdm

values = range(3)
with tqdm(total=len(values), file=sys.stdout) as pbar:
    for i in values:
        pbar.write('processed: %d%s' % (1 + i, ' ' * 50))
        pbar.update(1)
        sleep(1)

Ce qui nous donne:

processed: 1                                                  
processed: 2                                                  
processed: 3                                                  
100%|██████████| 3/3 [00:02<00:00,  1.53it/s]

Solution de contournement 2, définissez plutôt la description

Il peut en général être plus simple de ne pas avoir deux sorties mais de mettre à jour la description à la place, par exemple:

import sys
from time import sleep
from tqdm import tqdm

values = range(3)
with tqdm(total=len(values), file=sys.stdout) as pbar:
    for i in values:
        pbar.set_description('processed: %d' % (1 + i))
        pbar.update(1)
        sleep(1)

Avec la sortie (description mise à jour pendant son traitement):

processed: 3: 100%|██████████| 3/3 [00:02<00:00,  1.53it/s]

Conclusion

Vous pouvez généralement le faire fonctionner correctement avec tqdm ordinaire. Mais si tqdm_notebook fonctionne pour vous, utilisez-le simplement (mais vous ne lirez probablement pas aussi loin).

de1
la source
une alternative consiste à utiliser ce progressbar stackoverflow.com/a/34482761/1207193
eusoubrasileiro
C'est de loin la meilleure réponse.
Rafay
18

La plupart des réponses sont désormais dépassées. Mieux vaut si vous importez correctement tqdm .

from tqdm import tqdm_notebook as tqdm

entrez la description de l'image ici

Shritam Kumar Mund
la source
7
Il a encore changé:TqdmDeprecationWarning: This function will be removed in tqdm==5.0.0 Please use tqdm.notebook.tqdm instead of tqdm.tqdm_notebook
stason
10

Si les autres conseils ici ne fonctionnent pas et - tout comme moi - vous utilisez l' pandasintégration progress_apply, vous pouvez le laisser tqdmgérer:

from tqdm.autonotebook import tqdm
tqdm.pandas()

df.progress_apply(row_function, axis=1)

Le point principal ici réside dans le tqdm.autonotebookmodule. Comme indiqué dans leurs instructions d'utilisation dans les ordinateurs portables IPython , cela permet de tqdmchoisir entre les formats de barre de progression utilisés dans les ordinateurs portables Jupyter et les consoles Jupyter - pour une raison qui manque toujours d'enquêtes supplémentaires de mon côté, le format spécifique choisi par tqdm.autonotebookfonctionne bien pandas, alors que tous les autres n'ont pas 't, pour progress_applyspécifiquement.

Julio Cezar Silva
la source
9

Pour compléter la réponse d'oscarbranson: il est possible de choisir automatiquement des versions console ou notebook de la barre de progression en fonction de l'endroit où elle est exécutée:

from tqdm.autonotebook import tqdm

Plus d'informations peuvent être trouvées ici

mjarosie
la source
8

Aucune de ces réponses ne fonctionne pour moi. Je trouve que courir à la suite trie ce problème après une erreur (cela efface simplement toutes les instances de barres de progression en arrière-plan):

from tqdm import tqdm

# blah blah your code errored

tqdm._instances.clear()
James Owers
la source
1
Je vous remercie! Cependant, il jette une erreur si aucune instance n'existe. Je veux toujours l'utiliser avec des scripts et Hydrogen IDE. Voici mon code. try: # Avoids problem on notebooks / Hydrogen IDE tqdm.tqdm._instances.clear() except Exception: pass
Jacques Peeters
Oui, cela lèvera une exception si aucune instance n'existe. Y a-t-il un problème avec votre essai sauf approche?
James Owers
1

Pour tous ceux qui utilisent Windows et ne peuvent résoudre le problème des barres de duplication avec l'une des solutions mentionnées ici. J'ai dû installer le coloramapaquet comme indiqué dans les problèmes connus de tqdm qui l'ont résolu.

pip install colorama

Essayez-le avec cet exemple:

from tqdm import tqdm
from time import sleep

for _ in tqdm(range(5), "All", ncols = 80, position = 0):
    for _ in tqdm(range(100), "Sub", ncols = 80, position = 1, leave = False):
        sleep(0.01)

Ce qui produira quelque chose comme:

All:  60%|████████████████████████                | 3/5 [00:03<00:02,  1.02s/it]
Sub:  50%|██████████████████▌                  | 50/100 [00:00<00:00, 97.88it/s]
Nebulo
la source
0

Utilisez tqdm_notebook

from tqdm import 
tqdm_notebook as tqdm

x=[1,2,3,4,5]

for i in tqdm(len(x)):

    print(x[i])
Kranthi Kumar Valaboju
la source