Для тех, кто не знает, Гамильтон — это микрофреймворк общего назначения для спецификации потоков данных, например. указание преобразований Pandas. Это поможет вам структурировать вашу кодовую базу и улучшить ваш код, например. вы всегда пишете модульный тестируемый код преобразования с Гамильтоном. Это достигается за счет введения парадигмы, в которой функции должны быть написаны в самоуверенной, декларативной манере. См. этот пост TDS для более подробного ознакомления.
Одним из последствий использования Hamilton для разработки является то, что он заставляет вас с самого начала превращать ваши функции Python в модули. Если итерация в записной книжке — ваш способ разработки, то может показаться трудным использовать Hamilton в настройках записной книжки. В этом посте я объясню, как вы можете повторять свою работу с Hamilton DAG, не выходя из своего ноутбука.
Шаг 1 — Установите Jupyter и Hamilton
Я предполагаю, что вы уже настроили этот шаг. Но на всякий случай:
pip install notebook
pip install sf-hamilton
Затем, чтобы запустить сервер ноутбука, это должно быть просто:
jupyter notebook
Шаг 2 — Настройте файлы
- Запустите блокнот Jupyter.
- Перейдите в каталог, в котором вы хотите разместить свой ноутбук и функциональные модули Hamilton.
- Создайте файл(ы) Python. Для этого перейдите в «Новый › текстовый файл». Откроется вид редактора «файл». Назовите файл и дайте ему расширение
.py
. Как только вы сохраните его, вы увидите, что Jupyter теперь обеспечивает подсветку синтаксиса Python. Держите эту вкладку открытой, чтобы вы могли вернуться к ней, чтобы отредактировать этот файл. - Запустите блокнот, который вы будете использовать в другой вкладке браузера.
Шаг 3 — Основной процесс итерации
На высоком уровне вы будете переключаться между вкладками. Вы добавите функции в модуль python функций Hamilton, а затем импортируете/повторно импортируете этот модуль в свою записную книжку, чтобы получить изменения. Оттуда вы будете использовать Hamilton, как обычно, для запуска и выполнения вещей, а блокнот — для всех стандартных задач, для которых вы используете блокноты.
Давайте рассмотрим пример.
Вот функция, которую я добавил в наш функциональный модуль Гамильтона. Я назвал модуль some_functions.py
(очевидно, выберите лучшее имя для вашей ситуации).
import pandas as pd def avg_3wk_spend(spend: pd.Series) -> pd.Series: """Rolling 3 week average spend.""" print("foo") # will use this to prove it reloaded! return spend.rolling(3).mean()
И вот что я настроил в своей записной книжке, чтобы иметь возможность использовать Hamilton и импортировать этот модуль:
Ячейка 1: это просто импорт базовых вещей, которые нам нужны.
import importlib import pandas as pd from hamilton import driver
Ячейка 2: импортируйте функциональные модули Hamilton.
# import your hamilton function module(s) here import some_functions
Ячейка 3. Запускайте эту ячейку каждый раз, когда вносите изменения, и сохраняйте их в some_functions.py
.
# use this to reload the module after making changes to it. importlib.reload(some_functions)
Что это сделает, так это перезагрузит модуль и, следовательно, убедитесь, что код обновлен для использования.
Ячейка 4: использовать Гамильтон
config = {} dr = driver.Driver(config, some_functions) input_data = {'spend': pd.Series([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])} df = dr.execute(['avg_3wk_spend'], inputs=input_data)
Вы должны увидеть foo
в качестве вывода после запуска этой ячейки.
Итак, давайте теперь скажем, что мы повторяем наши функции Гамильтона. Перейдите к функциональному модулю Hamilton (в данном примере some_functions.py
) на другой вкладке браузера и измените print("foo")
на что-то другое, например. print("foo-bar").
Сохраните файл — он должен выглядеть примерно так:
def avg_3wk_spend(spend: pd.Series) -> pd.Series: """Rolling 3 week average spend.""" print("foo-bar") return spend.rolling(3).mean()
Вернитесь к своему ноутбуку и повторно запустите Cell 3 и Cell 4. Теперь вы должны увидеть другой напечатанный вывод, например. foo-bar
.
Поздравляем! Вам только что удалось повторить работу с Гамильтоном, используя блокнот Jupyter!
Подводя итог, вот как все выглядело с моей стороны:
- Вот как выглядит мой файл
some_functions.py
:
- Вот как выглядит мой блокнот:
Справка: я использую Google Colab и не могу сделать вышеперечисленное
Начиная с выпуска 1.8.0
, теперь у вас есть возможность встроенного определения функций с вашим драйвером, которые можно использовать для создания DAG. Мы настоятельно рекомендуем использовать этот подход только в случае крайней необходимости — таким образом очень легко создавать спагетти-код.
Например, предположим, что мы хотим добавить функцию для вычисления логарифма avg_3wk_spend
, а не добавлять его к some_functions.py
, мы можем выполнить следующие шаги непосредственно в нашей записной книжке:
# Step 1 - define function import numpy as np def log_avg_3wk_spend(avg_3wk_spend: pd.Series) -> pd.Series: “””Simple function taking the logarithm of spend over signups.””” return np.log(avg_3wk_spend)
Затем нам нужно создать «временный модуль python», чтобы разместить его. Мы делаем это, импортируя ad_hoc_utils
, а затем вызывая функцию create_temporary_module
, передавая нужные функции и предоставляя имя для модуля, который мы создаем.
# Step 2 - create a temporary module to house all notebook functions from hamilton import ad_hoc_utils temp_module = ad_hoc_utils.create_temporary_module( log_avg_3wk_spend, module_name='function_example')
Теперь вы можете обращаться с temp_module
как с модулем Python, передавать его вашему драйверу и использовать Hamilton как обычно:
# Step 3 - add the module to the driver and continue as usual dr = driver.Driver(config, some_functions, temp_module) df = dr.execute(['avg_3wk_spend', 'log_avg_3wk_spend'], inputs=input_data)
Предостережение с этим подходом:
Использование «временного модуля Python» не позволит масштабировать вычисления с помощью Ray, Dask или Pandas в Spark. Поэтому мы предлагаем использовать этот подход только в целях разработки.
Совет: вы можете напрямую импортировать функции
Преимущество принудительного включения функций Гамильтона в модуль заключается в том, что их очень легко повторно использовать в другом контексте. Например. другой блокнот или напрямую.
Например, легко использовать функции записной книжки напрямую, например так:
some_functions.avg_3wk_spend(pd.Series([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))
Что вызывает функцию avg_3wk_spend
, которую мы определили в модуле some_functions.py
.
Совет: вы можете использовать магию ipython для автоматической перезагрузки кода.
Откройте модуль Python и блокнот Jupyter рядом друг с другом, а затем добавьте в блокнот %autoreload ipython magic для автоматической перезагрузки ячейки:
from hamilton.driver import Driver # load extension %load_ext autoreload # configure autoreload to only affect specified files %autoreload 1 # import & specify my_module to be reloaded # i.e. this is the data transformation module that I have open in other tab %aimport my_module hamilton_driver = Driver({}, my_module) hamilton_driver.execute(['desired_output1', 'desired_output2'])
Затем вы должны следовать следующему процессу:
- Напишите свое преобразование данных в открытом модуле Python.
- В записной книжке создайте экземпляр драйвера Hamilton и протестируйте DAG с небольшим подмножеством данных.
- Из-за %autoreload модуль повторно импортируется с последними изменениями при каждом выполнении Hamilton DAG. Такой подход предотвращает неупорядоченное выполнение записных книжек, а функции всегда находятся в чистых файлах .py.
Кредит: Пост в блоге Тьерри Жана для этого последнего совета.
В заключение
Спасибо, что прочитали этот пост. Мы бы хотели, чтобы вы успешно использовали Hamilton. Не стесняйтесь оставлять вопросы/комментарии в нашем репозитории github (мы бы тоже хотели ⭐️!), или присоединяйтесь к нам на нашем слабом сервере, чтобы попросить о помощи или предложить предложения/улучшения.