Questa è una risposta alternativa nel caso in cui tqdm_notebook non funzioni per te.
Dato il seguente esempio:
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)
L'output sarebbe simile a questo (i progressi sarebbero visualizzati in rosso):
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
Il problema è che l'output di stdout e stderr viene elaborato in modo asincrono e separatamente in termini di nuove righe.
Se dice che Jupyter riceve su stderr la prima riga e quindi l'output "elaborato" su stdout. Quindi una volta ricevuto un output su stderr per aggiornare l'avanzamento, non tornerà indietro e aggiornerà la prima riga poiché aggiornerebbe solo l'ultima riga. Dovrà invece scrivere una nuova riga.
Soluzione 1, scrivere su stdout
Una soluzione alternativa sarebbe invece l'output di entrambi su stdout:
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)
L'output cambierà in (non più rosso):
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]
Qui possiamo vedere che Jupyter non sembra cancellare fino alla fine della linea. Potremmo aggiungere un'altra soluzione alternativa aggiungendo spazi. Ad esempio:
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)
Che ci dà:
processed: 1
processed: 2
processed: 3
100%|██████████| 3/3 [00:02<00:00, 1.53it/s]
Soluzione 2, impostare invece la descrizione
In generale potrebbe essere più semplice non avere due uscite ma aggiornare invece la descrizione, ad esempio:
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)
Con l'output (descrizione aggiornata durante l'elaborazione):
processed: 3: 100%|██████████| 3/3 [00:02<00:00, 1.53it/s]
Conclusione
Per lo più puoi farlo funzionare bene con tqdm semplice. Ma se tqdm_notebook funziona per te, basta usarlo (ma probabilmente non avresti letto così lontano).
tqdm_notebook
, posso anche fare normaliprint
s, e non influisce sulla barra di avanzamento.