J'utilise tqdm
pour imprimer la progression dans un script exécuté dans un cahier Jupyter. J'imprime tous les messages sur la console via tqdm.write()
. Cependant, cela me donne toujours une sortie biaisée comme ceci:
C'est-à-dire que 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 résoudre ça?
Essayez d’utiliser tqdm_notebook
au lieu de tqdm
, comme indiqué ici . C'est expérimental à ce stade, mais fonctionne plutôt bien dans la plupart des cas.
Cela pourrait être aussi simple que de changer votre importation en:
from tqdm import tqdm_notebook as tqdm
Bonne chance!
EDIT: Après les tests, il semble que tqdm
fonctionne correctement en "mode texte" dans le cahier Jupyter. C'est difficile à dire car vous n'avez pas fourni de exemple minimal , mais il semble que votre problème soit causé par une instruction print à chaque itération. L'instruction print génère un nombre (~ 0,89) entre chaque mise à jour de la barre d'état, ce qui perturbe la sortie. Essayez de supprimer la déclaration d'impression.
C'est une réponse alternative pour le cas où tqdm_notebook ne fonctionne pas pour vous.
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 (les progrès seraient affichés 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 de stdout et stderr est traitée de manière asynchrone et séparée en termes de nouvelles lignes.
Si Jupyter reçoit sur stderr la première ligne puis la sortie "traitée" sur stdout. Ensuite, une fois qu'il aura reçu une sortie sur stderr pour mettre à jour l'avancement, il ne reviendra pas en arrière et mettra à jour la première ligne car il ne mettrait à jour que la dernière ligne. Au lieu de cela, il devra écrire une nouvelle ligne.
Une solution de contournement serait de sortir les deux sur 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]
Nous pouvons voir ici que Jupyter ne semble pas effacer 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]
En général, il peut être plus simple de ne pas avoir deux sorties mais de mettre à jour la description, 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 le traitement):
processed: 3: 100%|██████████| 3/3 [00:02<00:00, 1.53it/s]
Vous pouvez généralement le faire fonctionner correctement avec plain tqdm. Mais si tqdm_notebook fonctionne pour vous, utilisez-le (mais vous ne liriez probablement pas si loin).
Si les autres astuces ne fonctionnent pas et que, comme moi, vous utilisez l'intégration pandas
via progress_apply
, vous pouvez laisser tqdm
le gérer:
from tqdm.auto import tqdm
tqdm.pandas()
df.progress_apply(row_function, axis=1)
Le point principal ici réside dans le module tqdm.auto
. Comme indiqué dans leurs instructions d'utilisation dans les ordinateurs portables IPython , cela fait tqdm
choisir entre les formats de barre de progression utilisés dans les ordinateurs portables Jupyter et les consoles Jupyter - pour une raison qui manque toujours Le format spécifique choisi par tqdm.auto
fonctionne sans problème dans pandas
, contrairement à tous les autres, pour progress_apply
en particulier.