Pandas 2.0 и асинхронный агностицизм

07 апреля 2023
Pandas 2.0 и асинхронный агностицизм

Апрель 2023 порадовал мажорным обновлением Pandas, самой известной библиотеки для анализа данных. Ещё мы рассказали о трудностях дистрибуции Python-приложений в экосистеме macOS, способах запуска приложений в браузере с помощью PyScript и асинхронном фреймворке Textual.

Долгожданный Pandas 2.0

Самая популярная библиотека для анализа данных обновилась до версии 2.0. Основным изменением стала интеграция с Apache Arrow. Это такой унифицированный формат хранения данных в памяти. Ранее Pandas использовал только библиотеку NumPy, которая была не всегда эффективной при работе с такими структурами данных, как DataFrame.

«Если хочешь сделать что-то хорошо, сделай это сам», — эта цитата Фердинанда Порше отлично отражает то, что сделал создатель Pandas, Уэс МакКинни (Wes McKinney). 10 лет назад он выступал с докладом о проблемах производительности, а спустя 4 года стал соучредителем Apache Arrow. Новый релиз соединил в себе сильные стороны обоих проектов.

Pandas часто критиковали за несколько особенностей. Отсутствующие значения долгое время были «головной болью» для специалистов по анализу данных. Они вызывали неявное изменение типа данных. Отсутствующие значения могли иметь разный тип, что в конечном итоге влияло на конечный dtype. Arrow решает эту проблему «из коробки»:

In [1]: df2 = pd.DataFrame({'a':[1,2,3, None]}, dtype='int64[pyarrow]')

In [2]: df2.dtypes
Out[2]:
a    int64[pyarrow]
dtype: object

In [3]: df2
Out[3]:
      a
0     1
1     2
2     3
3  <NA>

Второй особенность, за которую Pandas часто ругали — неэффективное управление строками. Оно и понятно — NumPy создавался вовсе не для обработки строк, а для числовых расчётов. Так что столбец со строковыми данными представлял собой набор указателей PyObject. Сами же данные были хаотично разбросаны по куче. Ни о какой эффективности тут речь, разумеется, не идёт. Промахи кэша и увеличенное потребление памяти — два постоянных спутника.

Чем больше было данных, тем ситуация становилась хуже. Даже экспериментальное расширение StringDtype не улучшило ситуацию. Apache Arrow архитектурно лишён этих недостатков и обращается с памятью эффективнее. Приятным бонусом стало существенное увеличение скорости (до 10 раз быстрее, чем NumPy) и уменьшение использования памяти (более чем в 2 раза).

Также внедрили механизм CoW (Copy-on-Write). Он часто используется в других системах для уменьшения накладных расходов на копирование. Это повышает безопасность данных, при использовании операций индексирования, а также производительность при совместной работе.

Пишем приложения для macOS

Python считается одним из наиболее универсальных языков. На нём можно написать всё что угодно. Но иногда простая задача написать приложение под macOS и распространить его, может превратиться в целый квест. Такая история была опубликована в блоге Python-разработчика Глифа Лефковица (Glyph Lefkowitz).

Экосистема Apple кажется заточенной под правильного разработчика, пишущего проприетарный код в нативном XCode на каком-нибудь Swift и платящего за учётную запись $99 в год. Конечно же, только на оборудовании Apple.

Если же вы на любом другом сетапе пишете приложение с открытым исходным кодом на Python в каком-нибудь VSCode или PyCharm — столкнётесь с рядом сложностей при попытке распространить его в экосистеме Apple. Чтобы подписать приложение, понадобится валидная учётная запись на портале Apple Developer. Можно использовать и веб-портал или ещё проще — подписать через XCode. Эта поистине монструозная IDE, весом в 11 Гб. Боль для тех, у кого нет доступа к высокоскоростному интернет-каналу.

Предположим, всё это пройдено и приложение подписано. Возникает новое препятствие — приложение должно быть подписано самой Apple, процедура «notarization». Подпись с заверением делается с помощью усиленной среды исполнения. Последняя несовместима с множеством вещей в Python, таких как cffi или ctypes. А если в пакете есть внутренние симлинки, то вообще пиши пропало.

Подводных камней в этом, казалось бы, простом процессе — множество. И вовсе не все они относятся к Python. Увы, сообщество разработчиков не может напрямую влиять на инструменты поставщика операционной системы. Документация, даже самая крутая, не решит все эти проблемы. Возможно, стоит создать инструмент, который бы интерактивно подсказывал и перепроверял каждый шаг разработчика на пути превращения его Python-кода в готовое к дистрибуции приложение для macOS.

Python в браузере

Всё больше интересных идей превращаются в готовые приложения с открытым исходным кодом. Проект PyScript начался с идеи «Было бы круто иметь возможность запускать код на Python прямо внутри браузера». Давайте возьмём Pyodide (портированный CPython), прикрутим к нему WASM и используем HTML в качестве интерфейса. Немного магии и мы получаем фреймворк для создания приложений на Python, которые будут работать везде, где есть современный браузер.

Попробовать PyScript можно тремя способами. Самый простой — на сайте проекта есть 18 демонстрационных примеров. Запуск любого приводит к открытию вкладки, загрузке Pyodide и запуску заранее написанного кода.

Второй вариант чуть интереснее — бета-версия сервиса, размещённая на pyscript.com. Чтобы начать работу, потребуется только создать учётную запись. После этого вы получите доступ к платформе, на которой можно вести разработку приложений и сразу же их запускать прямо в браузере. 

pyscript

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

Третий же способ — локальное развёртывание. В нужную веб-страницу добавляете скрипт и таблицу стилей:

<head>
    <link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
    <script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>

Сам же код прописываете непосредственно в веб-странице, например:

<py-config>
                plugins = [
                  "https://pyscript.net/latest/plugins/python/py_tutor.py"
                ]
</py-config>

<section class="pyscript">
    Hello world! <br>
    This is the current date and time, as computed by Python:
<py-script>
    from datetime import datetime
    now = datetime.now()
    display(now.strftime("%m/%d/%Y, %H:%M:%S"))
</py-script>
</section>

Сохраняете, приложение заработает. Никаких дополнительных телодвижений не требуется.

Не асинхронная асинхронность

Реализация асинхронного программирования с помощью паттерна async/await в Python 3.5 стало важным событием. С того момента можно было создавать сопрограммы, вычисления в которых не блокировали работу приложения. Это давало существенный прирост производительности. Особенность асинхронного программирования в том, что оно оптимизирует время исполнения и позволяет избежать простоев процессора.

Но у асинхронности есть и недостатки. По мнению эксперта по Python, Уилла МакГугана (Will McGugan), основная проблема асинхронности в том, что она имеет тенденцию бесконтрольного размножения в коде. Разработчики начинают использовать async для одного-единственного вызова или ещё хуже — добавляют async просто так, на всякий случай.

Но ведь паттерн async/await вовсе не единственная асинхронная техника. Есть ещё одна интересная, называется «Await me maybe». Она отлично работает с библиотекой asyncio. Термин впервые был придуман Саймоном Уиллисоном (Simon Willison). Смысл в том, чтобы асинхронная функция могла запускать callback либо с запланированной (неасинхронной) функцией, либо с корутиной (асинхронной через async def). Выглядит это следующим образом:

import asyncio
import inspect


def plain_old_function():
    return "Plain old function"

async def async_function():
    return "Async function"


async def await_me_maybe(callback):
    result = callback()
    if inspect.isawaitable(result):
        return await result
    return result


async def run_framework():
    print(
        await await_me_maybe(plain_old_function)
    )
    print(
        await await_me_maybe(async_function)
    )


if __name__ == "__main__":
    asyncio.run(run_framework())

Этот паттерн лёг в основу асинхронного фреймворка Textual. Он вообще не требует от разработчика использования ключевых слов async/await, хотя и позволяет расставить их по коду. Если захотите попробовать его в деле, то гайд по быстрому старту есть на сайте проекта.

Интересно посмотреть

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

Короткий и ёмкий формат занятий отлично подойдёт даже тем, у кого не слишком много свободного времени. Текстовые версии лекций доступны в нашем блоге на Хабре. Подписывайтесь и отправляйте эти видео своим друзьям, которые хотят начать изучать Python. И не забывайте нажать на «колокольчик», чтобы не пропустить новые видео.

Митапы

Онлайн

Python meetup

28 июня 2023

Рады сообщить, что у нас запланирован летний Python Meetup. Программа мероприятия формируется. Заявки на участие спикера принимаются до 10 июня. Видео с предыдущего митапа в студийном качестве 4K уже выложены на нашем YouTube-канале.

Теперь следить за митапами Evrone стало удобнее. В Telegram-канале Evrone meetups мы выкладываем анонсы с подробными описаниями докладов, а также студийные записи после мероприятий. А ещё, у нас можно выступить, мы поможем оформить вашу экспертизу в яркое выступление. Подписывайтесь и пишите @andrew_aquariuss, чтобы узнать подробности.

Регистрация

Вакансии

Удаленка / Офис

Evrone 

Мы рады новым Python-разработчикам. Удалённая работа с первого дня, помощь в подготовке выступлений на профессиональных конференциях, поощрение и оплата участия в Open-source проектах. Прозрачный способ увеличить грейд через обучение и проверку навыков под контролем ментора. Здесь есть понимание как организовать разработку комфортно и эффективно. Присоединяйтесь!

Подробнее

Подписаться
на Digest →
Важные новости и мероприятия без спама
Технологии которыми вы владеете и которые вам интересны
Ваш адрес электронной почты в безопасности - вот наша политика конфиденциальности.