Пишем прогресс-бары при помощи tqdm
В переводе с арабского tqdm (taqadum) означает прогресс; библиотека с таким названием используется как раз для создания индикаторов прогресса. Просто оберните любой итерируемый объект в функцию – tqdm(iterable)
– и готово.
Таким образом можно создать прогресс-бары для обработки данных, моделей машинного обучения или загрузки данных из интернета. Но сначала нужно установить библиотеку:
pip install tqdm
А теперь без лишних разговоров берите копируйте код ниже, запускайте у себя и любуйтесь. Библиотека tqdm помимо, собственно, самого прогресс-бара, показывает также количество итераций, время, затраченное на выполнение цикла, и частоту итераций в секунду. Видели ли вы что-то прекраснее сегодня?
from tqdm import tqdm for i in tqdm(range(10000)): pass
100%|🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩| 10000/10000 [00:00<00:00, 1764759.54it/s]
Ладно, давайте теперь научимся настраивать наши индикаторы и использовать при обработке датафреймов. Заодно узнаем о некоторых дополнительных фичах библиотеки.
tqdm и функции
В примере ниже мы создали функцию fun
, которая принимает целое число x
и исполняется с задержкой в x
секунд. Потом мы обернули tqdm
вокруг функции range
, которая будет запускать цикл на 10 итераций. Для выполнения первой итерации потребуется 0 секунд. Вторая итерация займет 1 секунду, и так далее. Для завершения цикла потребовалось 45 секунд, и мы при этом видим анимированный индикатор выполнения.
from tqdm import trange, tqdm from time import sleep # функция с задержкой исполнения def fun(x): sleep(x) return x # цикл с прогресс-баром for i in tqdm(range(10)): fun(i)
100%|██████████| 10/10 [00:45<00:00, 4.51s/it]
tqdm.notebook в списке
А здесь будем использовать модуль tqdm.notebook
для отображения прогресс-баров в Jupyter Notebook с помощью виджетов Ipython.
Сначала создаём простой список различных цветов. Затем с помощью цикла выведем их названия одно за другим с задержкой в одну секунду. Заворачиваем список в модуль, и радуемся анимированному индикатору.
from tqdm.notebook import tqdm colors = ["Blue", "Green", "Yellow", "White", "Gray", "Black"] for x in tqdm(colors): sleep(1) print(x)
Несколько индикаторов выполнения
С помощью вложенных циклов напишем несколько прогресс-баров, имитирующих визуализацию хода обучения модели машинного обучения.
trange
– это комбинация из функцииtqdm
, обёрнутой вокруг функцииrange
.- Внешний цикл будет выполняться за 10 итераций с задержкой 0,01 сек.
desc
используется для обозначения индикатора выполнения.- Внутренний цикл будет выполняться за 10 000 итераций с задержкой 0,001 сек.
Посмотрите, насколько круто выглядит анимация! Скопируйте код ниже, подшаманьте над ним немного на своё усмотрение и запустите.
from tqdm.notebook import trange for i in trange(10, desc="Traning Model on 10 Epochs"): sleep(0.01) for x in trange(10000, desc=f"Epoch {i}"): sleep(0.001)
tqdm для Data Science
В этой части мы соединим функционал библиотек tqdm
и pandas
и с помощью progress_apply применим функцию к датафрейму, чтобы добавить прогресс-бар.
Загружаем датасет
Сначала загрузим набор данных по бронированию отелей с Kaggle. Затем отобразим пять верхних строк датафрейма.
Набор содержит 119390 строк с данными о бронирований номеров в городских гостиницах и курортных отелях в период с 1 июля 2015 года по 31 августа 2017 года, включая фактически прибывшие и отмененные бронирования.
import pandas as pd df = pd.read_csv("hotel_booking.csv") df.head().to_frame()
Применение функции с помощью tqdm
Создадим новый столбец user_name
с именами клиентов.
- функция
tqdm.pandas
нужна для инициализации прогресс-бара в датафрейме. Добавим к нему название Processing the name colum. - Функция
user_name
приводит строку к нижнему регистру и заменяет пробелы на "-
". - Применим функцию к датафрейму с помощью
.progress_apply()
. Она аналогична функцииapply()
. А для функцииmap()
можно использовать.progress_map()
. - Отображаем три верхние строки нашего набора данных
# задаём имя прогресс-бару tqdm.pandas(desc="Processing the name column") # преобразование текста def user_name(text): return text.lower().replace(" ","-") # применение функции к столбцу df["user_name"] = df["name"].progress_apply(user_name) # вывод первых трёх строк df.head(3)
Утилита для параллельной обработки
Библиотека tqdm
нужна не только для написания прогресс-баров для циклов, в ней есть также утилиты для параллельной обработки, например, функция tqdm.contrib.concurrent
.
Давайте попробуем извлечь доменные имена из адресов электронной почты в столбце email
.
- Импортируем
process_map
изtqdm.contrib.concurrent
. - С помощью функции
provider_extraction
разделим текст сначала по знаку "@
", затем по знаку ".
". - Применяем функцию
process_map
к столбцуemail
. В качестве параметров укажемmax_worker
, равный 8, основываясь на количестве ядер процессора, и зададимchunksize
, равный 64. - Добавим имя прогресс-бара и настроим его цвет — пусть будет зелёный.
- Выводим первые пять строк столбца
email_provider
.
from tqdm.contrib.concurrent import process_map # функция для извлечения email def provider_extraction(email): return email.split("@")[1].split(".")[0] # применения функции к столбцу df["email_provider"] = process_map( provider_extraction, df["email"], max_workers=8, chunksize=64, desc="Extracting Email provider", colour='green' ) df["email_provider"].head().to_frame()
Мы поэкспериментировали с библиотекой tqdm, но она, на самом деле, может гораздо больше. Почитайте документацию и узнаете о других её возможностях.
Источник: KDNuggets
Перевод и адаптация: Екатерина Прохорова