Pandas НЕ для анализа данных

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Введение

В среде питонистов библиотека Pandas пользуется большой популярностью и по большей мере известна в контексте DataSciense и анализа данных. Как следует из русскоязычной википедии: "pandas — это программная библиотека на языке Python для обработки и анализа данных." Наверное, ни один Jupyter ноутбук не обходится без использования пандосовских DataFrame'ов. На самом деле, DataFrame пандас позволяет не только всячески манипулировать данными, но и выводить их в нужном формате, предоставляя широкие возможности для кастомизации. Например, использовали ли вы объекты класса Styler, входящего в состав Pandas? Мне показалось интересным взглянуть на Pandas с этой стороны.

На практике очень многие бизнес-задачи подразумевают работу с двумерными массивами данных или, проще говоря, таблицами. Как следствие, возникает потребность представлять такие данные в удобном для восприятия виде. Поэтому будет интересно поговорить о подходах к server-side рендеренгу таблиц в контексте веб-приложения на Python.

Актуальности данной теме добавляет тот факт, что подобной информации довольно мало как в интернете, так и в профессиональной литературе (возможность рендеринга таблиц в html не упоминается и в указанной выше статье википедии).

Проблема

Мы хотим отображать имеющиеся данные в виде html таблицы.

Часто одни и те же данные нужно представить в разных вариациях, например, отобразить на странице сайта, в email сообщении или формате Excel. Работая над одним из прошлых проектов, я столкнулся с трудно-поддерживаемыми, толстыми шаблонами веб-страниц, которые содержали html разметку для отображения таблиц с большим количеством данных. К тому же html шаблоны могли иметь различные вариации, например, для email уведомлений и т.д. Такой подход вызывает трудности при изменении структуры таблицы или данных.

Все последующие манипуляции будем проводить в контексте приложения на Django. В качестве адаптера БД имеется модель Customer, в качестве http представления имеем - CustomerListView. Код проекта с начальными условиями доступен на GitHub - commit# 8fdf785.

Решение в лоб - передать в контекст страницы итерируемый объект, содержащий строки данных, и средствами шаблонизатора итерироваться по нему формируя html код таблицы строка за строкой.

✅ Не требует использования дополнительных библиотек
❌ "Толстые" шаблоны таблиц
❌ Затруднена поддержка и внесение изменений
❌ Повторение работы при необходимости добавить вариацию таблицы (email, Excel и т.д.)

Используем DataFrame

Поскольку pandas уже входил в технологический стек проекта, было принято решение задействовать эту библиотеку для рендеринга таблиц в html.

DataFrame - это внутренняя структура Pandas для хранения таблицы и проведения операций над ней. Создадим новый объект DataFrame, передав нужные данные в конструктор класса, и отрендерим html воспользовавшись методом датафрейма - to_html():

# views.py

class CustomerListView(ListView):
    model = Customer
    paginate_by = 10

    def get_context_data(self, *, object_list=None, **kwargs):
        context = super().get_context_data(**kwargs)
        context['table'] = self.get_html_table(context['object_list'])
        return context

    def get_html_table(self, object_list: QuerySet):
        df = pd.DataFrame(
            data=object_list.values_list(),
            columns=[field.verbose_name for field in object_list.model._meta.get_fields()],
        )
        return df.to_html()

Метод get_html_table() возвращает html код таблицы, принимая на вход объект типа QuerySet - object_list из контекста ListView Django.

Конструктор класса DataFrame может принимать итерируемый объект, который содержит входные данные и список наименований столбцов.
Поэтому передаём данные в DataFrame, воспользовавшись методом QuerySet.values_list() для представления объектов БД в виде кортежей со значениями атрибутов объекта.

Таким образом, мы получили html таблицу, написав миниатюрный метод, состоящий из нескольких строк кода. Хотя стоит отметить, что в таком виде таблица не будет иметь какой-либо стилизации. Убедимся в этом, добавив полученный html в шаблон страницы, и взглянем на неё:

# customer_list.html

{% extends 'base.html' %}

{% block content %}
  <div class="col-6">
    {{ table|safe }}
  </div>
{% endblock %}
Изображение 1. Таблица без стилизации
Изображение 1. Таблица без стилизации

Код проекта из этого раздела доступен на GitHub - commit# 2005e31.

Используем средства стилизации

На самом деле метод DataFrame.to_html может принимать определённый перечень аргументов для обеспечения удобочитаемости таблицы на выходе. Например, можно настроить ширину границ ячеек, отображение индекса, заполнение пустых ячеек, выравнивание наименований столбцов и т.д. (с полным перечнем возможностей можно ознакомиться на соответствующей странице в документации).

# views.py
# def get_html_table(queryset):

return df.to_html(
            classes='table table-striped table-hover',
            border=0,
            index=False,
            na_rep='-',
            justify='left',
            columns=(
                Customer.id.field.verbose_name,
                Customer.status.field.verbose_name,
                Customer.name.field.verbose_name,
                Customer.source.field.verbose_name,
                Customer.target_volume.field.verbose_name,
                Customer.problematic.field.verbose_name,
            ),
        )

Аргумент columns определяет отображаемые столбцы таблицы, таким образом можно использовать один экземпляр DataFrame в различных сценариях вывода, когда требуется ограничить количество отображаемой информации (например для отправки таблицы в email).

С помощью аргумента classes можно определять css классы html элемента <table> и гибко управлять отображением таблицы с помощью css-правил. В приведённом примере я использую готовые стили css-библиотеки Bootstrap 5 для быстрой стилизации таблицы. Таким образом можно получить результат соотвтветсвующий стилю вашего проекта.

Изображение 2. Стилизация таблицы
Изображение 2. Стилизация таблицы

✅ Логика рендеринга объектов инкапсулирется в соответствующие классы
✅ Возможность изменения структуры таблиц без редактирования html шаблонов
❌ Ограниченные возможности контроля рендеринга html и стилизации

Код проекта из этого раздела доступен на GitHub - commit# 8108dd0.

Используем Styler

В предыдущем разделе мы получили html код, позволяющий отобразить удобочитаемую таблицу. Но чаще всего задачи разработки требуют более широкого контроля над процессом server-side рендеринга.

Класс Styler - это инcтрумент для гибкого контроля над процессом экспорта структур данных Pandas в различные сторонние форматы. Помимо рендеринга html, класс Styler позволяет экспортировать данные в формат Excel и др. Это весьма удобно, ведь в практике автоматизации бизнес-задач часто необходима возможность представления данных как в html так и в формате xlsx и др.

# views.py
# class CustomerListView(ListView):

def get_html_table(queryset: QuerySet) -> str:
    df = pd.DataFrame(
        data=queryset.values_list(),
        columns=[field.verbose_name for field in queryset.model._meta.get_fields()],
    )

    columns = ('id', 'status', 'name', 'source', 'target_volume', 'problematic')  # Список отображаемых столбцов

    styler = Styler(df)
    styler.format(na_rep='-')
    styler.hide(axis='index')
    styler.hide(
        subset=[field.verbose_name for field in Customer._meta.get_fields() if field.name not in columns],
        axis='columns',
    )

    return styler.to_html(table_attributes='class="table table-striped table-hover"')

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

Конструктор класса Styler принимает в качестве обязательного аргумента DataFrame Pandas. После инициализации объект класса предоставляет широкий набор инструментов стилизации. C полным перечнем методов класса Styler вы можете ознакомиться в соответствующем разделе документации.

✅ Логика рендеринга объектов инкапсулирется в соответствующие классы
✅ Возможность изменения структуры таблиц без редактирования html шаблонов

Источник: https://habr.com/ru/articles/822793/


Интересные статьи

Интересные статьи

В статье рассматриваются назначение, основные особенности и возможности Фреймворка “DBGridChart”  и OLAP – приложения “Экспресс_обработка.exe” (разработчик – Плещев В.В.,...
При развертывании почтового сервера Carbonio в формате On-Premise, системному администратору приходится решать вопрос хранения данных - главной ценности информационных систем. Для почтовых систем имен...
Помню, недавно выполнял задание на вакансию масленка после технического собеседования и открыл для себя порт Faker API на .net. Отличная библиотека для генерации тестовых объектов по моделям.
По мере развития приложения стоит проводить её аудит для выявления неявных деградаций в производительности. Недавно я проводил аудит раздела комментариев iFunny и написал...
GDPR создавали, чтобы дать гражданам ЕС больше контроля над персональными данными. И с точки зрения количества жалоб цель была «достигнута»: за прошедший год европейцы стали чаще сообщать о наруш...