В этом руководстве мы подробно рассмотрим tqdm и покажем, как внедрить мощное отслеживание прогресса в реальном времени в современные рабочие процессы Python. Мы начнём с вложенных индикаторов прогресса и ручного управления прогрессом, затем перейдём к практическим сценариям, таким как потоковая загрузка, обработка данных pandas, параллельное выполнение, структурированное логирование и асинхронные задачи.
Установка и настройка tqdm
Мы устанавливаем и настраиваем tqdm в среде Colab безопасным образом, сохраняя зависимости существующей среды. Импортируем все необходимые библиотеки, включая вспомогательные средства параллелизма и логирования из tqdm.contrib. Также выводим информацию о версии, чтобы убедиться, что наша среда выполнения стабильна, прежде чем продолжить.
1. Вложенные индикаторы прогресса (position/leave) + tqdm.write()
«`python
outer = trange(5, desc=»Внешний цикл», leave=True)
for i in outer:
inner = trange(20, desc=f»Внутренний цикл {i}», leave=False, position=1)
for j in inner:
time.sleep(0.01)
if j in (0, 10, 19):
tqdm.write(f» note: i={i}, j={j}»)
«`
2. Ручное управление прогрессом (unknown -> known total, update(), set_postfix())
«`python
items = list(range(1, 101))
pbar = tqdm(total=None, desc=»Обработка (обнаружение общего количества)», unit=»item»)
seen = 0
for x in items:
time.sleep(0.005)
seen += 1
if seen == 25:
pbar.total = len(items)
pbar.refresh()
pbar.update(1)
if x % 20 == 0:
pbar.set_postfix(last=x, sqrt=round(math.sqrt(x), 3))
pbar.close()
«`
3. Загрузка с потоковым прогрессом
«`python
url = «https://raw.githubusercontent.com/tqdm/tqdm/master/README.rst»
outpath = «/content/tqdmREADME.rst»
with requests.get(url, stream=True, timeout=30) as r:
r.raiseforstatus()
total = int(r.headers.get(«Content-Length», 0)) or None
chunk = 1024 * 32
with open(out_path, «wb») as f, tqdm(
total=total,
unit=»B»,
unit_scale=True,
unit_divisor=1024,
desc=»Загрузка README»,
miniters=1,
) as bar:
for part in r.itercontent(chunksize=chunk):
if not part:
continue
f.write(part)
bar.update(len(part))
print(«Сохранено:», out_path)
«`
4. Прогресс pandas progress_apply (Series) + DataFrame row-wise progress (safe)
«`python
tqdm.pandas()
df = pd.DataFrame({
«user_id»: range(1, 2001),
«value»: [random.random() for _ in range(2000)],
})
def heavy_fn(v: float) -> str:
time.sleep(0.0005)
s = f»{v:.10f}».encode(«utf-8»)
return hashlib.sha256(s).hexdigest()[:10]
df[«hash»] = df[«value»].progressapply(heavyfn)
df2 = df[[«value»]].copy()
df2[«hash2»] = [
heavy_fn(float(v))
for v in tqdm(df2[«value»].to_list(), desc=»Построчный хэш2″, total=len(df2))
]
df[«hash2»] = df2[«hash2»]
print(df.head(3))
«`
5. Конcurrency progress: threadmap / processmap
«`python
def cpuish(n: int) -> int:
x = 0
for i in range(50_000):
x = (x + (n * i)) % 1000003
return x
nums = list(range(80))
threadresults = threadmap(cpuish, nums, maxworkers=8, desc=»threadmap»)
print(«threadmap done:», len(threadresults))
procresults = processmap(cpuish, nums[:20], maxworkers=2, chunksize=2, desc=»processmap»)
print(«processmap done:», len(procresults))
«`
6. loggingredirecttqdm (логи не нарушают индикаторы прогресса)
«`python
logger = logging.getLogger(«demo»)
logger.setLevel(logging.INFO)
handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter(«%(levelname)s: %(message)s»))
logger.handlers = [handler]
with loggingredirecttqdm():
for k in tqdm(range(60), desc=»Работа с логами»):
time.sleep(0.01)
if k in (5, 25, 45):
logger.info(f»контрольная точка k={k}»)
«`
7. asyncio progress (as_completed) — Colab/Jupyter-safe
«`python
async def io_task(i: int):
await asyncio.sleep(random.uniform(0.02, 0.12))
return i, random.random()
async def run_async():
tasks = [asyncio.createtask(iotask(i)) for i in range(80)]
results = []
for fut in tqdm(asyncio.as_completed(tasks), total=len(tasks), desc=»асинхронные задачи»):
results.append(await fut)
return results
results = await run_async()
print(«async done:», len(results), «results»)
«`
Мы рассмотрели продвинутые шаблоны выполнения, включая многопоточность, многопроцессорность, структурированное логирование и отслеживание асинхронных задач. Мы использовали threadmap и processmap для распараллеливания рабочих нагрузок, связанных с процессором, с видимым прогрессом. Также мы безопасно обрабатывали asyncio в среде ноутбука, используя top-level await, обеспечивая плавное отслеживание прогресса без конфликтов с циклом событий.
В заключение мы интегрировали tqdm в синхронные, параллельные, логируемые и асинхронные среды. Мы увидели, как индикаторы прогресса улучшают наблюдаемость, улучшают ясность отладки и делают длительные рабочие нагрузки более прозрачными и удобными для пользователя. С помощью этих продвинутых шаблонов у нас теперь есть прочная основа для внедрения надёжного мониторинга прогресса в конвейеры данных, рабочие процессы машинного обучения, распределённые системы и реальные производственные приложения.
1. Какие методы и инструменты из статьи можно использовать для мониторинга прогресса в асинхронных задачах?
В статье описывается использование библиотеки tqdm для мониторинга прогресса в асинхронных задачах. В частности, упоминается метод asyncio progress (as_completed), который позволяет отслеживать прогресс выполнения асинхронных задач в среде Colab/Jupyter.
2. Как можно интегрировать tqdm в рабочие процессы с использованием pandas для обработки данных?
В статье показано, как использовать tqdm с pandas для мониторинга прогресса при применении функций к Series и DataFrames. Например, можно использовать метод progress_apply для применения функций к Series и построчный прогресс для DataFrames.
3. Какие преимущества даёт использование tqdm для мониторинга прогресса в высокопроизводительных рабочих процессах?
В статье отмечается, что использование tqdm позволяет улучшить наблюдаемость, ясность отладки и удобство работы с длительными рабочими нагрузками. Это особенно полезно в высокопроизводительных рабочих процессах, где важно иметь возможность отслеживать прогресс выполнения задач.
4. Какие методы ручного управления прогрессом описаны в статье и как они работают?
В статье описан метод ручного управления прогрессом, который позволяет изменять общее количество элементов для обработки и обновлять индикатор прогресса. Например, можно установить общее количество элементов для обработки с помощью метода total и обновлять индикатор прогресса с помощью метода update.
5. Какие инструменты и методы из статьи можно использовать для мониторинга прогресса при параллельном выполнении задач?
В статье показано, как использовать threadmap и processmap для распараллеливания рабочих нагрузок, связанных с процессором, с видимым прогрессом. Это позволяет отслеживать прогресс выполнения параллельных задач и обеспечивает более эффективное использование ресурсов.