tqdm в ноутбуке Jupyter
Я использую tqdm
для печати прогресса в сценарии, который я запускаю в ноутбуке Jupyter. Я печатаю все сообщения на консоль через tqdm.write()
. Тем не менее, это все еще дает мне перекошенный вывод, например:
То есть, каждый раз, когда должна печататься новая строка, на следующей строке печатается новый индикатор выполнения. Этого не происходит, когда я запускаю скрипт через терминал. Как я могу это решить?
Ответы
Ответ 1
Попробуйте использовать tqdm_notebook
вместо tqdm
, как описано здесь. Он экспериментальный на этом этапе, но в большинстве случаев работает очень хорошо.
Это может быть так же просто, как изменить импорт:
from tqdm import tqdm_notebook as tqdm
Удачи!
EDIT: после тестирования кажется, что tqdm
действительно отлично работает в текстовом режиме в ноутбуке Jupyter. Трудно сказать, потому что вы не представили минимальный пример, но похоже, что ваша проблема вызвана операцией печати на каждой итерации. Оператор печати выводит число (~ 0,89) между каждым обновлением строки состояния, которое испортит вывод. Попробуйте удалить инструкцию печати.
Ответ 2
Это альтернативный ответ для случая, когда 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
Проблема в том, что вывод в stdout и stderr обрабатывается асинхронно и отдельно в терминах новых строк.
Если говорят, что Jupyter получает на stderr первую строку, а затем "обработанный" вывод на stdout. Затем, как только он получает вывод на stderr для обновления прогресса, он не возвращается и не обновляет первую строку, поскольку он обновляет только последнюю строку. Вместо этого ему придется написать новую строку.
Обходной путь 1, запись в stdout
Одним из способов решения этой проблемы было бы вывести на 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. Но если tqdm_notebook работает для вас, просто используйте это (но тогда вы, вероятно, не читали бы так далеко).
Ответ 3
Если другие советы здесь не работают и - как и я - вы используете интеграцию pandas
через progress_apply
, вы можете позволить tqdm
справиться с этим:
from tqdm.auto import tqdm
tqdm.pandas()
df.progress_apply(row_function, axis=1)
Главное здесь заключается в модуле tqdm.auto
. Как указано в их инструкциях по применению в IPython тетрадях, это делает tqdm
выбор между штриховых форматов, используемых в ходе Jupyter ноутбуков и Jupyter консолей - по причине, по- прежнему не хватает дальнейших исследований на моей стороне, конкретный формат, выбранный tqdm.auto
работает плавно pandas
в то время как все остальные не, для progress_apply
специально.