Шаблон проектирования Python для написания масштабируемых конвейеров обработки данных
Некоторые из достоинств Python — его гибкость и простота. Однако эти способности — палка о двух концах. Если вы не приступите к разработке повторно используемого, управляемого и тестируемого кода на раннем этапе, вы столкнетесь с проблемами прогресса по мере масштабирования вашей кодовой базы.
При использовании модуля Python Pandas легко отказаться от объектно-ориентированного стиля кодирования. Распространенной ошибкой является написание быстрого кода, который сложно тестировать и масштабировать.
В этом посте показан шаблон проектирования для повторно используемого и не требующего обслуживания кода при обработке данных с помощью Pandas.
🪖 Цели поста
- Создайте конвейер метрик с Pandas
2. Конвейер рефакторинга, чтобы его можно было легко расширять и тестировать.
🐍 Кодовая база найдена здесь.
🦄 Набор данных
Мы будем использовать бесплатный набор данных от Kaggle, содержащий: «Полный список компаний-единорогов в мире».

Контекст
«Компания-единорог или стартап-единорог — это частная компания с оценкой более 1 миллиарда долларов. По состоянию на март 2022 года в мире насчитывается 1000 единорогов. Популярные бывшие единороги включают Airbnb, Facebook и Google. Варианты включают декакорн стоимостью более 10 миллиардов долларов и гектокорн стоимостью более 100 миллиардов долларов».
📊 Набор данных Kaggle Unicorn Companies найден здесь.
🧱 Построить конвейер метрик
Мы построим 3 таблицы статистики Unicorn, используя Pandas.
- Показатели на уровне страны
- Показатели временных рядов на уровне страны
- Метрики инвестора
🏆 Выигрышная комбинация методов панд
Мы будем использовать комбинацию методов Pandas, которые упростят манипулирование данными и сохранят наш пайплайн в чистоте.
pandas.DataFrame.explodeorpandas.DataFrame.meltpandas.DataFrame.groupbypandas.DataFrame.reset_indexpandas.merge
🌍 Статистика на уровне страны
Во-первых, мы рассчитаем количество единорогов в каждой стране и среднюю оценку единорогов (в миллиардах) в каждой стране.

📈 Пример графика с использованием выходной таблицы country_stats
График ниже является одним из примеров графика, созданного с помощью нашей таблицы country_stats. Мы можем быстро увидеть, что США лидируют в мире по общему количеству компаний-единорогов.

⏳ Временные ряды на уровне страны
Для этих показателей мы группируем по столбцам country и date_joined, чтобы подсчитать количество единорогов с течением времени и суммировать оценки.
💡 Обратите внимание, что ранее я отсортировал фрейм данных по date_joined.

➕ Совокупный временной ряд
До сих пор мы только генерировали метрики временных рядов в определенный момент времени. Тем не менее, легче для глаз, чтобы просмотреть совокупную сумму с течением времени.
Эти шаги берут сгенерированную таблицу time_series и используют расширяющееся окно для вычисления совокупной суммы.

📈 Пример графика с использованием выходной таблицы time_series
Приведенный ниже график временных рядов основан на наших совокупных результатах по количеству единорогов в стране. Мы видим, что с 2020–2021 годов США достигли траектории производства «единорогов», с которой не мог сравниться Китай. В то время как Индия и Великобритания, возможно, только начинают свой рост.

🧑💼 Статистика инвесторов
Генерация метрик инвестора более сложна. Инвесторы каждой компании хранятся в виде строки, разделенной запятыми.
Например, у Avant есть select_investors «RRE Ventures, Tiger Global, August Capital».
Мы хотим повторно использовать тот же формат кода, что и для метрик на уровне страны, чтобы использовать метод pandas.DataFrame.groupby. Это поможет нам провести рефакторинг позже.

🏗 Неразворотные инвесторы
Разворот является ключом к этому шаблону проектирования, так как мы хотим использовать метод groupby для отдельных инвесторов.
Используя pandas.DataFrame.explode, мы создаем дополнительный столбец для индивидуальных инвесторов. Обратите внимание, что теперь у нас есть несколько строк для каждой компании в нашей таблице.
💡 Здесь я использовалexplodeдля разворота. Еще один способ проверки:melt.

Следующим шагом является создание простой статистики инвесторов, количества компаний и оценки компаний в портфеле каждого инвестора.
📈 Пример графика с использованием investors_stats
На гистограмме ниже показано распределение инвесторов по общему количеству Единорогов в их портфеле. Мы видим распределение по степенному закону, когда у большинства инвесторов есть только 1 единорог, в то время как немногие инвестировали во многие. Этот тип распределения также можно найти в денежном богатстве населения и социальных сетях.

🔧 Трубопровод до сих пор
На данный момент у нас есть конвейер метрик, который выглядит довольно аккуратно, но всего мы генерируем только 8 метрик. Если бы мы расширили это число до 20–30 метрик, наш сценарий начал бы часто повторяться.
Формат нашего кода до сих пор представлял собой простой скрипт Python. Таким образом, наш код нельзя изолировать и протестировать.
Наш единственный вариант тестирования — запустить весь сценарий и оценить результат в сквозном тесте. Это не очень хорошо, так как это может занять много времени.
🚧 Рефакторинг конвейера
🚪Принцип открытия-закрытия
«Открыто для расширения, но закрыто для модификации».
Рефакторинг нашего кода, чтобы максимально следовать принципу открытия-закрытия.
- Переместите функции метрик в класс метрик и заручитесь использованием метода
pandas.DataFrame.apply. - Удалите повторные вызовы
pandas.DataFrame.groupbyс помощью функцииgenerate_metrics, используя встроенную в Python функциюgetattr. - Создайте файл конфигурации метрик, который передается нашей функции
generate_metrics, с метаданными, необходимыми для создания наших метрик.
💡 Ознакомьтесь с принципами дизайна SOLID здесь.
🧑🎓 Класс показателей
Перемещая наши метрики в класс, мы можем изолировать метрики и создавать модульные тесты для каждой метрики. Используя метод Pandas.DataFrame.apply, мы можем добавлять персонализированные метрики и использовать другие пакеты Python, не включенные в Pandas.
Следуя принципу открытия-закрытия, если бы мы хотели добавить показатели, мы бы создали новый класс, который наследует наш класс Metrics.
📂 Файл конфигурации
В файле конфигурации есть список метрик для каждой таблицы, которую мы хотим сгенерировать. Если мы хотим добавить или удалить метрики, изменить название и т. д., мы просто изменим файл конфигурации. Таким образом, мы не редактируем саму нашу кодовую базу.
⚙️ Создание функций метрик
Эта функция принимает наши данные Unicorn, экземпляр нашего класса Metrics и нашу конфигурацию показателей и возвращает кадр данных показателей.
Шаги:
- Использует
getattrдля создания объектаpandas.DataFrame.groupby.apply - Использует
getattrдля создания объекта метода класса Metrics (например,Metrics.count) - Вызывает объект
pandas.DataFrame.groupby.apply, передавая объект метода Metrics.
🪄 Рефакторинг конвейера
Наконец, мы подошли к нашему рефакторингу конвейера. Мы можем легко добавлять метрики в существующие таблицы, определяя новые классы метрик и добавляя их в наш файл конфигурации.
👀 Резюме
- Стандартизируйте код в нашем конвейере, чтобы использовать
pandas.DataFrame.groupby.applyдля выполнения преобразований наших данных. - Разверните данные, чтобы получить уникальные строки (для использования с
pandas.DataFrame.groupby). - Разместите метрики, которые мы хотим сгенерировать, в классе и передайте их
pandas.DataFrame.groupby.apply. - Используйте встроенную функцию Python
getattrи словарь метаданных для циклического просмотра наших метрик вместо повторных вызововpandas.DataFrame.groupby.apply.
✅ 🔀 Преимущества и недостатки
Преимущества
- Код является модульным и более управляемым для масштабирования наших показателей.
- Файл конфигурации дает нам больше гибкости для добавления и извлечения метрик, не касаясь кода.
- Легче протестировать функциональность нашего кода, так как он изолирован.
Компромиссы
- Больше кода для поддержки небольшого конвейера.
- Читабельность нашего кода была снижена.
- Сложнее отлаживать небольшой конвейер.
📚 Ресурсы
🐍 Кодовая база найдена здесь.
📊 Набор данных Kaggle Unicorn Companies найден здесь.
Сторонние библиотеки:
pandas.DataFrame.explodepandas.DataFrame.groupbypandas.DataFrame.reset_indexpandas.merge- Python встроен
getattr
Want to Connect? I'm just starting out my blogging journey. Let's Connect on Twitter!