tqdm в ноутбуке Jupyter
Я использую tqdm для печати прогресса в скрипте, который я запускаю в ноутбуке Jupyter. Я печатаю все сообщения на консоль через tqdm.write(). Тем не менее, это все еще дает мне искаженный вывод, например:
то есть каждый раз, когда новая строка должна быть напечатана, новый индикатор выполнения печатается на следующей строке. Этого не происходит когда я запускаю скрипт через терминал. Как я могу это решить?
2 ответов
попробуйте использовать tqdm_notebook вместо tqdm, как указано здесь. Это экспериментально на данном этапе, но работает довольно хорошо в большинстве случаев.
это может быть так же просто, как изменить ваш импорт на:
from tqdm import tqdm_notebook as tqdm
удачи!
EDIT: после тестирования, кажется, что tqdm на самом деле отлично работает в "текстовом режиме" в ноутбуке Jupyter. Трудно сказать, потому что вы не предоставили минимальный пример, но похоже, ваша проблема вызвана инструкцией печати на каждой итерации. Оператор print выводит число (~0.89) между каждым обновлением строки состояния, которое портит вывод. Попробуйте удалить инструкцию print.
это альтернативный ответ для случая, когда tqdm_notebook не работает для вас.
приводит следующий пример:
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)
выход будет выглядеть примерно так (прогресс будет отображаться красным):
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
проблема в том, что выход на стандартный вывод и stderr обрабатываются асинхронно и отдельно с точки зрения новых линий.
если сказать Jupyter получает на stderr первая строка, а затем "обработанный" вывод на stdout. Затем, как только он получает вывод на stderr для обновления прогресса, он не будет возвращаться и обновлять первую строку, поскольку он будет обновлять только последнюю строку. Вместо этого придется написать новую строку.
обходной путь 1, запись в 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)
выход изменится на (не более красный):
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]
здесь мы видим, что Jupyter не понятно до конца строки. Мы могли бы добавить еще один обходной путь для этого, добавив пробелы. Например:
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)
что дает нам:
processed: 1
processed: 2
processed: 3
100%|██████████| 3/3 [00:02<00:00, 1.53it/s]
обходной путь 2, Установите описание вместо
это может быть в целом более прямо вперед, чтобы не иметь два выхода, но обновить описание вместо этого, например:
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)
С выходом (описание обновлено, пока оно обработка):
processed: 3: 100%|██████████| 3/3 [00:02<00:00, 1.53it/s]
вывод
вы можете в основном заставить его работать нормально с простым tqdm. Но если ... --9-->tqdm_notebook работает для вас, просто используйте это (но тогда вы, вероятно, не читали бы так далеко).
