Научные вычисления и ноутбук Ipython: как организовать код?

Я использую ноутбук Ipython для своих исследований. По мере увеличения моего файла я постоянно извлекаю код, например, метод plot, метод подгонки и т.д.

Я думаю, мне нужен способ организовать это. Есть ли хороший способ сделать это?


В настоящее время я делаю это:

data/
helpers/
my_notebook.ipynb
import_file.py

Я храню данные в data/ и извлекаю helper method в helpers/ и деля их на такие файлы, как plot_helper.py, app_helper.py и т.д.

Я суммирую импорт в import_file.py,

from IPython.display import display

import numpy as np
import scipy as sp
import pandas as pd
import matplotlib as mpl
from matplotlib import pyplot as plt
import sklearn
import re

И затем я могу импортировать все, что мне нужно, в .ipynb в верхней ячейке, как

введите описание изображения здесь

Структуру можно увидеть на https://github.com/cqcn1991/Wind-Speed-Analysis

Одна из проблем, которые я имею прямо сейчас, заключается в том, что у меня слишком много подмодулей в helpers/, и трудно подумать, какой метод следует поместить в какой файл.

Я думаю, что возможным способом является организация в pre-processing, processing, post-processing.

ОБНОВЛЕНИЕ:

Мой большой исследовательский ноутбук jupyter: https://cdn.rawgit.com/cqcn1991/Wind-Speed-Analysis/master/output_HTML/marham.html

Верхняя ячейка standard import + magic + extentions

%matplotlib inline
%load_ext autoreload
%autoreload 2

from __future__ import division
from import_file import *
load_libs()

Ответы

Ответ 1

Существует много способов организовать проект исследования ipython. Я управляю командой из 5 Ученых Данных и 3 Инженеров Данных, и я нашел, что эти советы хорошо работают для нашего usecase:

Это краткое изложение моей беседы PyData London:

http://www.slideshare.net/vladimirkazantsev/clean-code-in-jupyter-notebook

1. Создание общей (многопроектной) библиотеки utils

Скорее всего, вам придется повторно использовать/повторять код в разных исследовательских проектах. Начните реорганизовывать эти вещи в пакет "common utils". Сделайте файл setup.py, надавите модуль на github (или аналогичный), чтобы члены команды могли "установить" его из VCS.

Примерами функциональных возможностей для ввода являются:

  • Функции хранилища данных или хранения данных
  • общие функции построения
  • повторно используемые методы математики/статистики

2. Разделите свой жирный мастер-блокнот на меньшие ноутбуки

По моему опыту, хорошая длина файла с кодом (любой язык) - это всего лишь несколько экранов (100-400 строк). Jupyter Notebook по-прежнему является исходным файлом, но с выходом! Чтение ноутбука с 20 + клетками очень сложно. Мне нравятся мои ноутбуки с максимальным размером 4-10 ячеек.

В идеале у каждого ноутбука должен быть один "триплет" гипотез-данных-выводов.

Пример разделения ноутбука:

1_data_preparation.ipynb

2_data_validation.ipynb

3_exploratory_plotting.ipynb

4_simple_linear_model.ipynb

5_hierarchical_model.ipynb

playground.ipynb

Сохраните вывод 1_data_preparation.ipynb, чтобы выбрать df.to_pickle('clean_data.pkl'), csv или быстрый DB и использовать pd.read_pickle("clean_data.pkl") в верхней части каждого ноутбука.

3. Это не Python - это IPython Notebook

Что делает ноутбук уникальным, это ячейки. Используйте их хорошо. Каждая ячейка должна быть триплетной "идея-исполнение-вывод". Если ячейка ничего не выводит - соединитесь со следующей ячейкой. Импорт ячейки не должен выводить ничего - это ожидаемый результат для него.

Если ячейка имеет несколько выходов - возможно, стоит ее разделить.

Скрытие импорта может быть или не быть хорошей идеей:

from myimports import *

Ваш читатель может захотеть выяснить, что именно вы импортируете, чтобы использовать тот же материал для своих исследований. Поэтому используйте с осторожностью. Однако мы используем его для pandas, numpy, matplotlib, sql.

Скрытие "секретного соуса" в /helpers/model.py плохо:

myutil.fit_model_and_calculate(df)

Это может спасти вас при вводе текста, и вы удалите дубликат кода, но вашему соавтору придется открыть другой файл, чтобы выяснить, что происходит. К сожалению, ноутбук (jupyter) является довольно негибкой и базовой средой, но вы все равно не хотите, чтобы ваш читатель оставил его для каждой части кода. Надеюсь, что в будущем IDE улучшится, но пока сохранить "секретный соус" внутри ноутбука. Хотя "скучные и очевидные утилиты" - везде, где вы считаете нужным. DRY все еще применяется - вам нужно найти баланс.

Это не должно мешать вам упаковывать повторно используемый код в функции или даже небольшие классы. Но "квартира лучше, чем вложенная".

4. Держите ноутбуки в чистоте

Вы должны иметь возможность "reset и запустить все" в любой момент времени.

Каждый повторный запуск должен быть быстрым! Это означает, что вам, возможно, придется инвестировать в написание некоторых функций кеширования. Может быть, вы даже захотите поместить их в свой модуль "common utils".

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

После того, как вы закончите исследование - вы не сделали с записной книжкой. Рефакторинг.

5. Создайте модуль проекта, но будьте очень избирательным

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

"Чистый код читается как хорошо написанная проза" Грэди Буч (разработчик UML)

6. Сервер узла Jupyter в облаке для всей команды

У вас будет одна среда, поэтому каждый может быстро просмотреть и проверить исследования без необходимости соответствовать среде (хотя conda делает это довольно легко).

И вы можете настроить значения по умолчанию, такие как стиль/цвета mpl, и сделать matplot lib inline, по умолчанию:

В ~/.ipython/profile_default/ipython_config.py

Добавить строку c.InteractiveShellApp.matplotlib = 'inline'

7. (экспериментальная идея) Запустите ноутбук из другого ноутбука с различными параметрами

Довольно часто вы можете повторно запустить весь ноутбук, но с другими входными параметрами.

Для этого вы можете структурировать свой исследовательский ноутбук следующим образом: Поместите params словарь в первую ячейку из исходной записной книжки.

params = dict(platform='iOS', 
              start_date='2016-05-01', 
              retention=7)
df = get_data(params ..)
do_analysis(params ..)

И в другом (более высоком логическом уровне) ноутбуке выполните его с помощью этой функции:

def run_notebook(nbfile, **kwargs):
    """
    example:
    run_notebook('report.ipynb', platform='google_play', start_date='2016-06-10')
    """

    def read_notebook(nbfile):
        if not nbfile.endswith('.ipynb'):
            nbfile += '.ipynb'

        with io.open(nbfile) as f:
            nb = nbformat.read(f, as_version=4)
        return nb

    ip = get_ipython()
    gl = ip.ns_table['user_global']
    gl['params'] = None
    arguments_in_original_state = True

    for cell in read_notebook(nbfile).cells:
        if cell.cell_type != 'code':
            continue
        ip.run_cell(cell.source)

        if arguments_in_original_state and type(gl['params']) == dict:
            gl['params'].update(kwargs)
            arguments_in_original_state = False

Является ли этот "шаблон дизайна" полезным, пока еще не видно. У нас был некоторый успех - по крайней мере, мы прекратили дублирование ноутбуков только для изменения нескольких входов.

Рефакторинг ноутбука в класс или модуль прерывает быстрый цикл обратной связи "idea-execute-output", который предоставляют ячейки. И, ИМХО, не "ipythonic"..

8. Напишите (единичные) тесты для общей библиотеки в блокнотах и ​​запустите с py.test

Существует плагин для py.test, который может обнаруживать и запускать тесты внутри ноутбуков!

https://pypi.python.org/pypi/pytest-ipynb

Ответ 2

В идеале вы должны иметь библиотечную иерархию. Я бы организовал его следующим образом:

Пакет wsautils

Фундаментальный пакет самого низкого уровня [Без зависимостей]

stringutils.py: содержит самые основные файлы, такие как манипуляции с строкой dateutils.py: методы обработки даты

Пакет wsadata​​h2 >

  • Анализ данных, манипуляций с данными, вспомогательные методы для Pandas и т.д.
  • Зависит от [wsautils]
    • pandasutils.py
    • parseutils.py
    • jsonutils.py [это также можно найти в wsautils]
    • и др.

Пакет wsamath (или wsastats)

Утилиты, модели, PDF, CDF, связанные с математикой [Зависит от wsautils, wsadata] Содержит: - chanceutils.py - statutils.py и др.

Пакет wsacharts [или wsaplot]

  • GUI, Plotting, Matplotlib, GGplot и т.д.
  • Зависит от [wsautils, wsamath]
    • histogram.py
    • pichart.py
    • и т.д.. Просто идея, вы также можете просто иметь один файл здесь, называемый chartutils или что-то.

Вы получаете идею. Создавайте больше библиотек по мере необходимости, не делая слишком много.

Несколько советов:

  • Тщательно следуйте принципам хорошего управления пакетами python. Прочтите это http://python-packaging-user-guide.readthedocs.org/en/latest/installing/
  • Обеспечить строгое управление зависимостями с помощью script или инструмента, для которого нет круговых зависимостей между пакетами
  • Хорошо определить имя и назначение каждой библиотеки/модуля, чтобы другие пользователи также могли интуитивно определить, куда должен идти метод/утилита.
  • Следуйте хорошим стандартам кодирования питона (см. PEP-8)
  • Напишите тестовые примеры для каждой библиотеки/пакета
  • Используйте хороший редактор (PyCharm - хороший для Python/iPython)
  • Документируйте свои API, методы

Наконец, помните, что есть много способов скинуть кошку, и выше это просто одно, что мне нравится. НТН.