Slide 1

Slide 1 text

КАК МЫ УСКОРИЛИ ПРОГНОЗ СПРОСА ПУТЕМ МИГРАЦИИ С PANDAS 
 НА POLARS Moscow Python Meetup #96 Python-разработчик 
 в ecom.tech (ex Samokat.tech) Кирилл Гладких КАК МЫ УСКОРИЛИ ПРОГНОЗ СПРОСА ПУТЕМ МИГРАЦИИ С PANDAS 
 НА POLARS

Slide 2

Slide 2 text

Гладких Кирилл • 5 лет разработки на Python • Работаю в ecom.tech в команде продуктовизации ML-моделей 
 для серисов Самоката • Люблю котиков и путешествия

Slide 3

Slide 3 text

ритейл реального времени в цифрах заказов в день Самокат 
 доставляет своим клиентам с доступом к быстрой 
 доставке продуктов уникальных посетителей
 Мегамаркета каждый месяц пунктов выдачи заказов 
 и постаматов по всей России 673 тыс. 127 городов 74 тыс. 40 млн

Slide 4

Slide 4 text

План (01) Проблематика: Система прогноза спроса в Самокате (02) Как устроена обработка, и с какими проблемами столкнулись. (03) Решение и альтернативы
 Почему выбрали Polars? (04) Сравнение быстродействия библиотек

Slide 5

Slide 5 text

СИСТЕМА ПРОГНОЗА СПРОСА

Slide 6

Slide 6 text

Цели: Уменьшить количество списаний или время недоступности товаров. Требования 
 от бизнеса [01]

Slide 7

Slide 7 text

Цели: Уменьшить количество списаний или время недоступности товаров. Повышение выручки 
 компании. Требования 
 от бизнеса Конечная цель [01] [02]

Slide 8

Slide 8 text

Цели: Уменьшить количество списаний или время недоступности товаров. Прогноз продаж: Спрогнозировать количество проданного товара на каждый день для каждого даркстора 
 на 7 недель вперёд 
 по 46 категориям товаров 
 
 Например: 
 Бакалея, Мясо, Гигиена 
 и т.п. Повышение выручки 
 компании. Требования 
 от бизнеса Конечная цель [01] [02] Решение: [01]

Slide 9

Slide 9 text

Цели: Уменьшить количество списаний или время недоступности товаров. Прогноз продаж: Спрогнозировать количество проданного товара на каждый день для каждого даркстора 
 на 7 недель вперёд 
 по 46 категориям товаров 
 
 Например: 
 Бакалея, Мясо, Гигиена 
 и т.п. Повышение выручки 
 компании. Отправка прогноза: Отправить прогнозы потребителям в S3 
 и в Kafka [02] Требования 
 от бизнеса Конечная цель [01] [02] Решение: [01]

Slide 10

Slide 10 text

Характеристики системы прогноза спроса Airflow Kubernetes DWH MSSQL S3 S3 Demand- prediction

Slide 11

Slide 11 text

Характеристики системы прогноза спроса Технические
 характеристики: Бизнес- характеристики: Airflow Kubernetes DWH MSSQL S3 S3 Demand- prediction

Slide 12

Slide 12 text

Характеристики системы прогноза спроса Технические
 характеристики: Бизнес- характеристики: Написан на Python + Pandas + Polars + scikit Airflow Kubernetes DWH MSSQL S3 S3 Demand- prediction

Slide 13

Slide 13 text

Характеристики системы прогноза спроса Технические
 характеристики: Бизнес- характеристики: ~100 Гб данных для обработки ежедневно Написан на Python + Pandas + Polars + scikit Airflow Kubernetes DWH MSSQL S3 S3 Demand- prediction

Slide 14

Slide 14 text

Характеристики системы прогноза спроса Технические
 характеристики: Бизнес- характеристики: ~100 Гб данных для обработки ежедневно Написан на Python + Pandas + Polars + scikit Запускается в k8s на ноде 
 (500 Гб оперативной памяти 
 и 64 CPU ядра) Airflow Kubernetes DWH MSSQL S3 S3 Demand- prediction

Slide 15

Slide 15 text

Характеристики системы прогноза спроса Технические
 характеристики: Бизнес- характеристики: ~100 Гб данных для обработки ежедневно Написан на Python + Pandas + Polars + scikit Запускается в k8s на ноде 
 (500 Гб оперативной памяти 
 и 64 CPU ядра) 20 375 строк python кода Airflow Kubernetes DWH MSSQL S3 S3 Demand- prediction

Slide 16

Slide 16 text

Характеристики системы прогноза спроса Технические
 характеристики: Бизнес- характеристики: ~100 Гб данных для обработки ежедневно Написан на Python + Pandas + Polars + scikit Запускается в k8s на ноде 
 (500 Гб оперативной памяти 
 и 64 CPU ядра) 20 375 строк python кода Много бизнес-логики 
 на разных этапах 
 формирования данных Airflow Kubernetes DWH MSSQL S3 S3 Demand- prediction

Slide 17

Slide 17 text

Характеристики системы прогноза спроса Технические
 характеристики: Бизнес- характеристики: ~100 Гб данных для обработки ежедневно Написан на Python + Pandas + Polars + scikit Запускается в k8s на ноде 
 (500 Гб оперативной памяти 
 и 64 CPU ядра) 20 375 строк python кода Много бизнес-логики 
 на разных этапах 
 формирования данных 268М регулярных предсказаний еженедельно Airflow Kubernetes DWH MSSQL S3 S3 Demand- prediction

Slide 18

Slide 18 text

Характеристики системы прогноза спроса Технические
 характеристики: Бизнес- характеристики: ~100 Гб данных для обработки ежедневно Написан на Python + Pandas + Polars + scikit Запускается в k8s на ноде 
 (500 Гб оперативной памяти 
 и 64 CPU ядра) 20 375 строк python кода Много бизнес-логики 
 на разных этапах 
 формирования данных 268М регулярных предсказаний еженедельно 100М предсказаний 
 с учетом промо акции Airflow Kubernetes DWH MSSQL S3 S3 Demand- prediction

Slide 19

Slide 19 text

и с какими проблемами мы столкнулись: Как устроена 
 обработка ML model 
 Train Data SpawnProcess warehouse=1 ML-App with multiprocessing SpawnProcess warehouse=2 SpawnProcess warehouse=n …

Slide 20

Slide 20 text

и с какими проблемами мы столкнулись: Как устроена 
 обработка ML model 
 Train Data SpawnProcess warehouse=1 ML-App with multiprocessing SpawnProcess warehouse=2 SpawnProcess warehouse=n Резкое увеличение количества дарксторов. (01) …

Slide 21

Slide 21 text

и с какими проблемами мы столкнулись: Невозможность дальнейшего масштабирования
 
 на тот момент мы уже потребляли 
 около 450 Гб оперативной памяти. (02) Как устроена 
 обработка ML model 
 Train Data SpawnProcess warehouse=1 ML-App with multiprocessing SpawnProcess warehouse=2 SpawnProcess warehouse=n Резкое увеличение количества дарксторов. (01) …

Slide 22

Slide 22 text

и с какими проблемами мы столкнулись: Перестали укладываться 
 в SLA (24 часа). Невозможность дальнейшего масштабирования
 
 на тот момент мы уже потребляли 
 около 450 Гб оперативной памяти. (02) (03) Как устроена 
 обработка ML model 
 Train Data SpawnProcess warehouse=1 ML-App with multiprocessing SpawnProcess warehouse=2 SpawnProcess warehouse=n Резкое увеличение количества дарксторов. (01) …

Slide 23

Slide 23 text

РЕШЕНИЕ ПРОБЛЕМЫ

Slide 24

Slide 24 text

Альтернативные способы решения


Slide 25

Slide 25 text

Альтернативные способы решения
 Использовать Spark вместо Pandas 
 Spark позволил бы масштабироваться горизантально, но пришлось бы переписать весь проект, на что ресурсов не было.

Slide 26

Slide 26 text

Альтернативные способы решения
 Использовать Spark вместо Pandas 
 Spark позволил бы масштабироваться горизантально, но пришлось бы переписать весь проект, на что ресурсов не было. Увеличить количество процессов Мы уже уперлись 
 в максимальный размер 
 ноды (500 Гб оперативной памяти).

Slide 27

Slide 27 text

Альтернативные способы решения
 Использовать Spark вместо Pandas 
 Spark позволил бы масштабироваться горизантально, но пришлось бы переписать весь проект, на что ресурсов не было. Увеличить количество процессов Мы уже уперлись 
 в максимальный размер 
 ноды (500 Гб оперативной памяти). Переписать отдельные участки кода без использования apply()
 
 Как вариант, но не даст того же прироста по скорости,
 как рефакторинг вместе 
 с миграцией на Polars.

Slide 28

Slide 28 text

Альтернативные способы решения
 Использовать Spark вместо Pandas 
 Spark позволил бы масштабироваться горизантально, но пришлось бы переписать весь проект, на что ресурсов не было. Увеличить количество процессов Мы уже уперлись 
 в максимальный размер 
 ноды (500 Гб оперативной памяти). Переписать отдельные участки кода без использования apply()
 
 Как вариант, но не даст того же прироста по скорости,
 как рефакторинг вместе 
 с миграцией на Polars. Аналитическая БД?
 
 (1) Много расчетов и бизнес- логики, которую трудно поддерживать на уровне запросов к БД.
 
 (2) Исходные данные — 
 из нескольких источников.

Slide 29

Slide 29 text

Установить профилировщик Профилировщик позволяет в удобном виде проанализировать и найти наиболее долгие функции.
 Например: line_profiler. Сбор аналитики После настройки профилировщик необходимо запустить обработку. Поиск медленных функций После сбора аналитики находим самые медленные функций. Оцениваем количество кода и целесообразность рефакторинга. Создание задач на рефакторинг Оцениваем сроки миграции, создаём задачи на рефакторинг. 
 Приоритет задачи определяется количеством кода для рефакторинга. Как организовать процесс миграции Сперва необходимо найти «bottleneck» функции

Slide 30

Slide 30 text

Пишем 
 юнит-тесты Если в проекте нет 
 юнит-тестов, то нужно их написать. 
 Берутся реальные входные и выходные датасеты для функции. Рефакторинг Переписываем целую функцию с pandas на Polars. Из Polars в Pandas конвертируем методом to_pandas() Оценка результата С помощью профилировщика оцениваем результат рефакторинга. Далее начинаем процесс рефакторинга Как организовать процесс миграции

Slide 31

Slide 31 text

Результаты миграции Достижения • Переписав несколько функций, мы получили ускорение нашего пайплайна с 24 до 16 часов, что позволило нам уложиться в SLA.
 [01]

Slide 32

Slide 32 text

Результаты миграции Достижения • Переписав несколько функций, мы получили ускорение нашего пайплайна с 24 до 16 часов, что позволило нам уложиться в SLA.
 • На полный процесс миграции одной 
 функции уходило от нескольких дней 
 до 3 недель.
 [01]

Slide 33

Slide 33 text

Результаты миграции Достижения • Переписав несколько функций, мы получили ускорение нашего пайплайна с 24 до 16 часов, что позволило нам уложиться в SLA.
 • На полный процесс миграции одной 
 функции уходило от нескольких дней 
 до 3 недель.
 • Уменьшили расходы на инфраструктуру. [01]

Slide 34

Slide 34 text

Результаты миграции Достижения • Переписав несколько функций, мы получили ускорение нашего пайплайна с 24 до 16 часов, что позволило нам уложиться в SLA.
 • На полный процесс миграции одной 
 функции уходило от нескольких дней 
 до 3 недель.
 • Уменьшили расходы на инфраструктуру. Минусы [02] [01]

Slide 35

Slide 35 text

Результаты миграции Достижения • Переписав несколько функций, мы получили ускорение нашего пайплайна с 24 до 16 часов, что позволило нам уложиться в SLA.
 • На полный процесс миграции одной 
 функции уходило от нескольких дней 
 до 3 недель.
 • Уменьшили расходы на инфраструктуру. Минусы • Увеличилась длительность юнит-тестов. [02] [01]

Slide 36

Slide 36 text

Результаты миграции Достижения • Переписав несколько функций, мы получили ускорение нашего пайплайна с 24 до 16 часов, что позволило нам уложиться в SLA.
 • На полный процесс миграции одной 
 функции уходило от нескольких дней 
 до 3 недель.
 • Уменьшили расходы на инфраструктуру. Минусы • Увеличилась длительность юнит-тестов. • В случае нового увеличения количества складов необходима дальнейшая оптимизация или миграция на кластерные вычисления. [02] [01]

Slide 37

Slide 37 text

POLARS И ЕГО ПРЕИМУЩЕСТ ВА

Slide 38

Slide 38 text

Что за Polars? и почему 
 мы его выбрали?

Slide 39

Slide 39 text

Что за Polars и почему мы его выбрали? Polars — это библиотека для работы с наборами данных 
 (Dataframes) поверх механизма запросов OLAP, реализованный 
 на Rust с использованием формата столбцов Apache Arrow 
 в качестве модели памяти.

Slide 40

Slide 40 text

МНОГОПОТОЧНЫЕ ВЫЧИСЛЕНИЯ (01) В отличии от Pandas большинство операций в Polars выполняются на всех доступных ядрах процессора. Также есть возможность конфигурировать количество активных потоков. Что за Polars и почему мы его выбрали? Polars — это библиотека для работы с наборами данных 
 (Dataframes) поверх механизма запросов OLAP, реализованный 
 на Rust с использованием формата столбцов Apache Arrow 
 в качестве модели памяти.

Slide 41

Slide 41 text

МНОГОПОТОЧНЫЕ ВЫЧИСЛЕНИЯ (01) В отличии от Pandas большинство операций в Polars выполняются на всех доступных ядрах процессора. Также есть возможность конфигурировать количество активных потоков. НЕ НУЖНО СОЗДАВАТЬ КЛАСТЕР 
 ДЛЯ ВЫЧИСЛЕНИЙ (02) В инструментах, как Spark, необходимо поднимать кластер вычислений. Что за Polars и почему мы его выбрали? Polars — это библиотека для работы с наборами данных 
 (Dataframes) поверх механизма запросов OLAP, реализованный 
 на Rust с использованием формата столбцов Apache Arrow 
 в качестве модели памяти.

Slide 42

Slide 42 text

МНОГОПОТОЧНЫЕ ВЫЧИСЛЕНИЯ (01) В отличии от Pandas большинство операций в Polars выполняются на всех доступных ядрах процессора. Также есть возможность конфигурировать количество активных потоков. ВОЗМОЖНОСТЬ ЧАСТИЧНОЙ МИГРАЦИИ (03) Можно проводить рефакторинг кода 
 по функциям, так как датафрейм можно быстро сконвертировать в Pandas формат. НЕ НУЖНО СОЗДАВАТЬ КЛАСТЕР 
 ДЛЯ ВЫЧИСЛЕНИЙ (02) В инструментах, как Spark, необходимо поднимать кластер вычислений. Что за Polars и почему мы его выбрали? Polars — это библиотека для работы с наборами данных 
 (Dataframes) поверх механизма запросов OLAP, реализованный 
 на Rust с использованием формата столбцов Apache Arrow 
 в качестве модели памяти.

Slide 43

Slide 43 text

МНОГОПОТОЧНЫЕ ВЫЧИСЛЕНИЯ (01) В отличии от Pandas большинство операций в Polars выполняются на всех доступных ядрах процессора. Также есть возможность конфигурировать количество активных потоков. ВОЗМОЖНОСТЬ ЧАСТИЧНОЙ МИГРАЦИИ (03) Можно проводить рефакторинг кода 
 по функциям, так как датафрейм можно быстро сконвертировать в Pandas формат. НЕ НУЖНО СОЗДАВАТЬ КЛАСТЕР 
 ДЛЯ ВЫЧИСЛЕНИЙ (02) В инструментах, как Spark, необходимо поднимать кластер вычислений. СПЕЦИФИКАЦИЯ ARROW (04) Данные в памяти хранятся в формате Arrow, что позволяет эффективнее использовать процессор. Что за Polars и почему мы его выбрали? Polars — это библиотека для работы с наборами данных 
 (Dataframes) поверх механизма запросов OLAP, реализованный 
 на Rust с использованием формата столбцов Apache Arrow 
 в качестве модели памяти.

Slide 44

Slide 44 text

Отсутствие индекса Apache Arrow vs Numpy В Pandas каждой строке назначается индекс, который обозначает позицию строки в датафрейме. В Polars отказались от этого механизма. Pandas для хранения данных использует Numpy, но Polars использует Arrow, модель которого более оптимизированно использует оперативную память для хранения данных. Ключевые отличия Pandas и Polars

Slide 45

Slide 45 text

Параллельные 
 вычисления Для параллелизации вычислений 
 в Pandas необходимо использовать инструменты Dask или Modin. Ленивые вычисления В Polars есть механизм оптимизации плана запроса, что позволяет ускорить вычисления. Ключевые отличия Pandas и Polars

Slide 46

Slide 46 text

Параллелизация вычислений Разбиение данных Данные разбиваются на несколько групп и вычисления производятся параллельно над каждой из групп. Хеш таблицы В операциях groupby и join создаются хеш таблицы, в Polars они вычисляются параллельно.

Slide 47

Slide 47 text

Ленивая оптимизация запросов Для любого ленивого запроса Polars имеет:
 ▪ неоптимизированный план с набором шагов кода, как мы его предоставили ▪ оптимизированный план с изменениями, внесёнными оптимизатором запросов. Имеется возможность рассмотреть как неоптимизированные, так и оптимизированные планы запросов с помощью визуализации и путём их печати в виде текста.

Slide 48

Slide 48 text

Ленивая 
 оптимизация 
 запросов
 WITH COLUMNS [col(“Fare”).round()] WITH COLUMNS [col(“Fare”).round()] Parquet SCAN titanic.parquet
 π 3/12;
 σ[(col(“Survived”))=(1)] Parquet SCAN titanic.parquet
 π */12;
 σ None FILTER BY [(col(“Survived”))==(1)] π 3/3 Без оптимизаций запросов С оптимизацией запросов

Slide 49

Slide 49 text

Операция Pandas Polars Импорт import pandas as pd import polars as pl Выбор Данных df['a'] df.loc[:,'a'] df.select('a') Фильтрация df.loc[df["a"] < 10,] df[df["a"] < 10] df.query("a < 10") df.filter(pl.col('a') < 10) Присваивание по столбцам df.assign(b=lambda df_: df_.a * 10) df["b"] = df["a"] * 10 df.with_columns(a=pl.col("a") * 10) Ленивые вычисления - scan_csv("data.csv").some_computations().collect() Пропущенные значения float('nan'), np.nan, None null float('nan'), np.nan == NotaNumber Сравнение синтаксиса Polars и Pandas

Slide 50

Slide 50 text

СРАВНЕНИЕ БЫСТРОДЕЙСТВ ИЯ БИБЛИОТЕК

Slide 51

Slide 51 text

Тесты быстродействия ▪ 80 Гб оперативной 
 памяти, DDR4-3200 Набор данных:
 Parquet файлы разных размеров: 
 200, 400, 800, 
 1600, 3200, 6400 Мб ▪ 20 CPU ядер, Intel® Xeon® 
 Gold 6354, 3.00 GHz Машина для проведения тестов:

Slide 52

Slide 52 text

Сравнение Polars с альтернативами
 Чтение parquet файлов (меньше = лучше)


Slide 53

Slide 53 text

Группировка и агрегация данных

Slide 54

Slide 54 text

Фильтрация

Slide 55

Slide 55 text

Операция inner join (merge)

Slide 56

Slide 56 text

Фильтрация is_in

Slide 57

Slide 57 text

ВОПРОС Ы ВОПРО СЫ t.me/gladkir