Интерактивное управление в Jupyter Notebooks

Python

Вряд ли найдётся занятие бесполезнее, чем вновь и вновь запускать одну и ту же ячейку, немного меня значение входных данных и параметров. Несмотря на то, что я понимаю это, часто замечаю себя за запуском одной и той же ячейки, внося в неё незначительные изменения. Например, используя другое значение для функции, выбирая различные диапазоны данных для анализа, или, меняя цветовую схему визуализации. Это не только непродуктивно, но и отвлекает от основной задачи анализа данных.

Решение проблемы — интерактивное управление, которое позволяет менять переменные, не внося изменений в код. К счастью, как это часто происходит в случае с Python, люди уже столкнулись с этой проблемой и был создан продукт, решающий её. В этой статье мы увидим, как работать с IPywidgets, инструментом интерактивного управления. Эта библиотека превращает блокнот Jupyter из статичного текстового документа в диалоговую панель, удобную для визуализации и работы с данными.

Вы можете посмотреть на пример интерактивного блокнота в этой статье на mybinder.

Интерактивное управление в Jupyter Notebooks — IT-МИР. ПОМОЩЬ В IT-МИРЕ 2020

К сожалению, визуализация виджетов IPython не поддерживается на GitHub или на nbviewer, поэтому для просмотра примеров запустите блокнот локально.

Интерактивное управление в Jupyter Notebooks — IT-МИР. ПОМОЩЬ В IT-МИРЕ 2020

Начало работы с IPywidgets

Первым делом устанавливаем библиотеку: pip install ipywidgets. Как только установка завершится, активируйте виджеты при помощи команды:

jupyter nbextension enable --py widgetsnbextension

Чтобы использовать с JupyterLab, выполните команду:

jupyter labextension install @jupyter-widgets/jupyterlab-manager

Для того, чтобы импортировать ipywidgets в блокнот, создайте ячейку со следующим содержанием:

import ipywidgets as widgets
from ipywidgets import interact, interact_manual

Интерактивное управление в одну строчку

Пусть нашими данными будет статистика статей в Medium (это моя действительная статистика).

Интерактивное управление в Jupyter Notebooks — IT-МИР. ПОМОЩЬ В IT-МИРЕ 2020

Предположим, что нужно посмотреть статьи со значением просмотра больше 1000. Вот как можно это сделать:

df.loc[df['reads'] > 1000]

Но, если мы хотим вывести статьи, у которых больше 500 хлопков, нам придётся написать ещё одну строчку:

df.loc[df['claps'] > 500]

Было бы гораздо удобнее, если бы мы могли менять эти параметры: и колонку, и пороговое значение без изменений кода. Попробуем выполнить это:

@interact
def show_articles_more_than(column='claps', x=5000):
    return df.loc[df[column] > x]
Интерактивное управление в Jupyter Notebooks — IT-МИР. ПОМОЩЬ В IT-МИРЕ 2020

@interact автоматически создаёт текстовое поле и слайдер для выбора колонки и числа! Декоратор смотрит на введённые параметры и создаёт панель диалогового управления, основываясь на типах данных. Теперь мы можем разделять данные, не меняя код.

Возможно, вы заметили, что в нашем виджете x может быть отрицательным, а в графу column необходимо вводить существующие названия колонок. Это неудобство можно исправить, задав возможные параметры функции.

# Interact with specification of arguments
@interact
def show_articles_more_than(column=['claps', 'views', 'fans', 'reads'], x=(10, 100000, 10)):
    return df.loc[df[column] > x]
Интерактивное управление в Jupyter Notebooks — IT-МИР. ПОМОЩЬ В IT-МИРЕ 2020

Теперь у нас есть выпадающий список с названиями колонок и слайдер с ограниченной область значений (формат: (начало, конец, шаг)). За подробностями о параметрах обратитесь к документации.

Используем тот же декоратор @interact для того чтобы преобразовать функцию в интерактивный виджет. Например, если есть директория с изображениями, которые мы хотим просмотреть:

import os
from IPython.display import Image

@interact
def show_images(file=os.listdir('images/')):
    display(Image(fdir+file))
Интерактивное управление в Jupyter Notebooks — IT-МИР. ПОМОЩЬ В IT-МИРЕ 2020

Теперь мы можем просматривать все изображения, не перезапуская ячейку каждый раз. Это полезно, если, например, вы создаёте свёрточную нейронную сеть и хотите увидеть изображения, на которых классификатор допустил ошибку.

На самом деле, область использования этих виджетов ничем не ограничена. Ещё одним примером рассмотрим поиск корреляции между двумя столбцами:

@interact
def correlations(column1=list(df.select_dtypes('number').columns),
     column2=list(df.select_dtypes('number').columns)):
 print(f"Correlation: {df[column1].corr(df[column2])}")
Интерактивное управление в Jupyter Notebooks — IT-МИР. ПОМОЩЬ В IT-МИРЕ 2020

На GitHub можно найти ещё больше примеров использования ipywidgets.


Виджеты для графиков

Интерактивные виджеты особенно полезны для данных, которые мы хотим визуализировать. Используем тот же самый декоратор @interact:

import cufflinks as cf
@interact
def scatter_plot(x=list(df.select_dtypes('number').columns), 
                 y=list(df.select_dtypes('number').columns)[1:],
                 theme=list(cf.themes.THEMES.keys()), 
                 colorscale=list(cf.colors._scales_names.keys())):
    df.iplot(kind='scatter', x=x, y=y, mode='markers', 
             xTitle=x.title(), yTitle=y.title(), 
             text='title',
             title=f'{y.title()} vs {x.title()}',
             theme=theme, colorscale=colorscale)
Интерактивное управление в Jupyter Notebooks — IT-МИР. ПОМОЩЬ В IT-МИРЕ 2020

Здесь мы используем комбинацию cufflinks + plotly для создания интерактивного графика с интерактивным управлением при помощи виджетов.

Возможно, вы заметили, что график достаточно медленно обновляется. В этом случае, мы можем использовать @interact_manual с отдельной кнопкой для обновления.

Интерактивное управление в Jupyter Notebooks — IT-МИР. ПОМОЩЬ В IT-МИРЕ 2020

Теперь график будет обновлён только после нажатия кнопки. Это полезно для функций с относительно долгим временем выполнения.


Расширение возможностей интерактивного управления

Мы можем сами создавать виджеты и использовать их в функции interact. Один из моих любимых виджетов — DatePicker. Допустим, у нас есть функция stats_for_article_published_between, которая получает на вход начальную и конечную дату и выдаёт все статьи, опубликованные в этот промежуток. Для виджета используем следующий код:

# Create interactive version of function with DatePickers
interact(stats_for_article_published_between,
        start_date=widgets.DatePicker(value=pd.to_datetime('2018-01-01')),
        end_date=widgets.DatePicker(value=pd.to_datetime('2019-01-01')))

Теперь у нас есть два виджета для выбора даты. ходные данные передаются в функцию (подробности в блокноте):

Интерактивное управление в Jupyter Notebooks — IT-МИР. ПОМОЩЬ В IT-МИРЕ 2020

Точно так же мы можем сделать функцию, которая создаёт график столбцов до определённой даты.

Интерактивное управление в Jupyter Notebooks — IT-МИР. ПОМОЩЬ В IT-МИРЕ 2020

Если мы хотим, чтобы значение одного виджета зависело от значения другого, используем функцию observe. Здесь мы модифицируем функцию просмотра изображений так, чтобы выбирать и директорию, и картинку. Список изображений меняется при смене директории.

# Create widgets
directory = widgets.Dropdown(options=['images', 'nature', 'assorted'])
images = widgets.Dropdown(options=os.listdir(directory.value))
 
# Updates the image options based on directory value
def update_images(*args):
    images.options = os.listdir(directory.value)
 
# Tie the image options to directory value
directory.observe(update_images, 'value') 

# Show the imagesdef show_images(fdir, file):    display(Image(f'{fdir}/{file}')) 
_ = interact(show_images, fdir=directory, file=images)
Интерактивное управление в Jupyter Notebooks — IT-МИР. ПОМОЩЬ В IT-МИРЕ 2020
Интерактивное управление в Jupyter Notebooks — IT-МИР. ПОМОЩЬ В IT-МИРЕ 2020

Повторное использование виджетов

Если мы хотим использовать виджет в нескольких ячейках, присвоим ей значение выходных данных функции interact:

def show_stats_by_tag(tag):
    return(df.groupby(f'<tag>{tag}').describe()[['views', 'reads']])

stats = interact(show_stats_by_tag,
               tag=widgets.Dropdown(options=['Towards Data Science',
               'Education', 'Machine Learning', 'Python',
               'Data Science']))

Теперь из любой ячейки мы можем вызвать stat.widget.

Интерактивное управление в Jupyter Notebooks — IT-МИР. ПОМОЩЬ В IT-МИРЕ 2020

Это позволяет использовать виджеты во всём блокноте. Заметьте, что виджеты привязаны друг к другу, а это значит, что при изменении его в одной ячейке он автоматически поменяется и в остальных


Конечно, мы не узнали о всех возможностях библиотеки ipywidgets. Мы научились привязывать значения друг к другу, создавать виджеты, кнопки, панели с вкладками и анимацию. Для дальнейшего использования и для знакомства с полным функционалом ознакомьтесь с документацией. Надеюсь, что даже та маленькая часть возможностей этой библиотеки, о которой я рассказал, дала понять вам то, как сильно она упрощает вашу работу.

Интерактивное управление в Jupyter Notebooks — IT-МИР. ПОМОЩЬ В IT-МИРЕ 2020

Заключение

Jupyter Notebook — прекрасная среда для обработки и анализа данных. Однако, она одна не предоставляет удобный функционал. Использование расширений и интерактивных виджетов значительно улучшает блокнот и делает работу специалистов науки о данных более эффективной!

Специально для сайта ITWORLD.UZ. Новость взята с сайта NOP::Nuances of programming