TQDM в ноутбуке Jupyter
Я использую tqdm
чтобы распечатать прогресс в сценарии, я бегу в блокноте Jupyter. Я печатаю все сообщения на консоль через tqdm.write()
, Тем не менее, это все еще дает мне искаженный вывод примерно так:
То есть каждый раз, когда должна быть напечатана новая строка, новая строка прогресса печатается на следующей строке. Этого не происходит, когда я запускаю скрипт через терминал. Как я могу решить это?
13 ответов
Попробуйте использовать tqdm_notebook
вместо tqdm
, как изложено здесь. На данном этапе это экспериментально, но в большинстве случаев работает довольно хорошо.
Это может быть так же просто, как изменить ваш импорт на:
from tqdm import tqdm_notebook as tqdm
Удачи!
РЕДАКТИРОВАТЬ: после тестирования, кажется, что tqdm
на самом деле отлично работает в "текстовом режиме" в ноутбуке Jupyter. Трудно сказать, потому что вы не предоставили минимальный пример, но похоже, что ваша проблема вызвана оператором print в каждой итерации. Оператор печати выдает число (~0,89) между каждым обновлением строки состояния, что портит вывод. Попробуйте удалить оператор печати.
Это альтернативный ответ для случая, когда 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, запись в стандартный вывод
Один из обходных путей - вместо этого вывести оба на стандартный вывод:
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 работает для вас, просто используйте это (но тогда вы, вероятно, не прочитали бы это далеко).
Большинство ответов сейчас устарели. Лучше, если вы правильно импортируете tqdm.
from tqdm import tqdm_notebook as tqdm
Чтобы завершить ответ Оскарбрансона: можно автоматически выбрать версию индикатора выполнения для консоли или ноутбука в зависимости от того, откуда он запускается:
from tqdm.autonotebook import tqdm
Более подробную информацию можно найти здесь
У меня ничего из вышеперечисленного не работает. Я обнаружил, что запуск следующих видов этой проблемы после ошибки (он просто очищает все экземпляры индикаторов выполнения в фоновом режиме):
from tqdm import tqdm
# blah blah your code errored
tqdm._instances.clear()
Если другие советы здесь не работают и - так же, как я - вы используете 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
в частности.
Для всех, кто работает в Windows и не может решить проблему дублирования полос с помощью любого из упомянутых здесь решений. Мне пришлось установитьcolorama
пакет, как указано в известных проблемах tqdm, которые его исправили.
pip install colorama
Попробуйте это на следующем примере:
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)
Что даст что-то вроде:
All: 60%|████████████████████████ | 3/5 [00:03<00:02, 1.02s/it]
Sub: 50%|██████████████████▌ | 50/100 [00:00<00:00, 97.88it/s]
С использованием
Python 3.9.2
а также
tqdm==4.62.3
:
from tqdm.notebook import tqdm
for item in tqdm(list_of_items):
do_something(item)
tqdm
автоматически загружает индикатор выполнения подгонки либо для обычного кода, либо для интерактивной среды через
from tqdm.auto import tqdm
Используйте tqdm_notebook
from tqdm import
tqdm_notebook as tqdm
x=[1,2,3,4,5]
for i in tqdm(len(x)):
print(x[i])
Это работает как положено, если вы делаете следующее:
pbar = tqdm(range(10))
try:
for i in pbar:
sleep(1)
if i==5:
raise NotImplementedError()
finally:
pbar.close()
или же
with tqdm(range(10)) as pbar:
for i in pbar:
sleep(1)
if i==5:
raise NotImplementedError()
В моем случае мне просто нужно было обновить ipywidgets, чтобы избавиться от лишней печати при использовании обычного
from tqdm import tqdm
.
Еще один пример индикатора выполнения с использованием tqdm
from tqdm import tqdm
my_list = list(range(100))
with tqdm(total=len(my_list)) as pbar:
for x in my_list:
pbar.update(1)