科学计算与发展Ipython Notebook:如何组织代码?

时间:2016-04-05 13:27:29

标签: python jupyter-notebook

我正在使用Ipython Notebook进行研究。随着我的文件越来越大,我不断提取代码,比如绘图方法,拟合方法等。

我想我需要一种方法来组织这个。有什么好办法吗?

目前,我这样做:

data/
helpers/
my_notebook.ipynb
import_file.py

我将数据存储在data/,并将helper method提取到helpers/,然后将其划分为plot_helper.pyapp_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顶部单元格中导入我需要的所有内容

enter image description here

可以在https://github.com/cqcn1991/Wind-Speed-Analysis

看到结构

我现在遇到的一个问题是我在helpers/有太多的子模块,很难想出应该将哪个方法放入哪个文件中。

我认为可行的方法是在pre-processingprocessingpost-processing进行整理。

更新:

我的大型研究笔记本: 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()

5 个答案:

答案 0 :(得分:38)

有许多方法可以组织ipython研究项目。我正在管理一个由5名数据科学家和3名数据工程师组成的团队,我发现这些技巧对我们的用例非常有用:

这是我的PyData伦敦演讲摘要:

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

<强> 1。创建共享(多项目)工具库

您很可能必须在不同的研究项目中重复使用/重复某些代码。开始将这些东西重构为常见的工具&#34;包。制作setup.py文件,将模块推送到github(或类似的),以便团队成员可以&#34; pip install&#34;来自VCS。

放入的功能示例包括:

  • 数据仓库或存储访问功能
  • 常见的绘图功能
  • 可重复使用的数学/统计方法

<强> 2。将您的胖型笔记本电脑拆分为较小的笔记本电脑

根据我的经验,带代码(任何语言)的文件长度只有几个屏幕(100-400行)。 Jupyter Notebook仍然是源文件,但有输出!阅读20多个细胞的笔记本电脑非常困难。我喜欢我的笔记本最多有4-10个单元。

理想情况下,每个笔记本应该有一个假设 - 数据 - 结论&#34;三元组。

拆分笔记本的示例:

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或快速数据库,并使用每个笔记本顶部的pd.read_pickle("clean_data.pkl")

第3。它不是Python - 它是IPython Notebook

笔记本电脑的独特之处在于单元。好好利用它们。 每个单元格应该是#idea; idea-execution-output&#34;三重。如果单元格没有输出任何内容 - 与下面的单元格结合使用。导入单元格应该不输出任何内容 - 这是它的预期输出。

如果单元格输出很少 - 可能值得分割它。

隐藏进口可能是也可能不是好主意:

from myimports import *

您的读者可能想要确定您要导入的内容,以便将相同的内容用于研究。所以要谨慎使用。我们确实将它用于pandas, numpy, matplotlib, sql

隐藏&#34;秘制酱&#34;在/helpers/model.py中很糟糕:

myutil.fit_model_and_calculate(df)

这可能会节省您的输入,并且您将删除重复的代码,但您的协作者必须打开另一个文件才能找出正在进行的操作。不幸的是,笔记本(jupyter)是非常不灵活和基本的环境,但你仍然不想强迫你的读者为每一段代码留下它。我希望将来IDE能够改进,但是现在,保持&#34;秘密酱油#34;在笔记本内。虽然&#34;无聊和明显的工具&#34; - 无论你认为合适的地方。 DRY仍然适用 - 你必须找到余额。

这不应该阻止您将可重复使用的代码打包到函数甚至是小类中。但是&#34; flat比嵌套&#34;更好。

<强> 4。保持笔记本清洁

你应该能够&#34;重置&amp;全部运行&#34;在任何时间点。

每次重播都应该快!这意味着您可能需要投资编写一些缓存功能。也许你甚至想把它们放进你的常用工具中。模块。

每个单元格应该可执行多次,而无需重新初始化笔记本。这可以节省您的时间并使代码更加健壮。 但它可能取决于先前单元格创建的状态。使每个细胞完全独立于上述细胞是一种反模式IMO。

完成研究后 - 你没有完成笔记本电脑。重构。

<强> 5。创建项目模块,但要非常有选择性

如果您继续使用绘图或分析功能 - 请将其重构为此模块。但根据我的经验,人们希望阅读和理解笔记本,而无需打开多个util子模块。因此,与普通Python相比,在这里命名您的子例程更为重要。

&#34;干净的代码读起来就像写得好的散文&#34; Grady Booch(UML开发人员)

<强> 6。在整个团队的云端托管Jupyter服务器

您将拥有一个环境,因此每个人都可以快速查看和验证研究,而无需匹配环境(即使conda使这非常简单)。

默认情况下,您可以配置默认值,例如mpl样式/颜色,并使matplot lib内联:

~/.ipython/profile_default/ipython_config.py

添加第c.InteractiveShellApp.matplotlib = 'inline'

<强> 7。 (实验想法)从另一个具有不同参数的笔记本中运行笔记本

通常您可能需要重新运行整个笔记本,但使用不同的输入参数。

为此,您可以按如下方式构建研究笔记本: 将 params 字典放在&#34;源笔记本&#34;的第一个单元格中。

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

这是否&#34;设计模式&#34;证明有用还有待观察。我们取得了一些成功 - 至少我们停止复制笔记本只是为了改变一些输入。

将笔记本重构为类或模块,打破&#34; idea-execute-output&#34;的快速反馈循环。细胞提供。并且,恕我直言,不是&#34; ipythonic&#34; ..

<强> 8。在笔记本中对共享库进行写(单元)测试,并使用py.test

运行

py.test有一个插件可以在笔记本中发现并运行测试!

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

答案 1 :(得分:2)

理想情况下,您应该拥有库层次结构。我会按如下方式组织:

包裹wsautils

基本的,最低级别的包[无依赖性]

stringutils.py:包含最基本的文件,如字符串操作 dateutils.py:日期操作方法

包wsadata

  • 解析数据,数据帧操作,Pandas的辅助方法等。
  • 取决于[wsautils]
    • pandasutils.py
    • parseutils.py
    • jsonutils.py [这也可以在wsautils中]

包wsamath(或wsastats)

数学相关的实用程序,模型,PDF,CDF [取决于wsautils,wsadata] 包含:    - probabilityutils.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/
  • 通过脚本或工具实施严格的依赖关系管理,使包之间没有循环依赖关系
  • 很好地定义每个库/模块的名称和用途,以便其他用户也可以直观地告诉方法/实用程序应该去哪里
  • 遵循良好的python编码标准(参见PEP-8)
  • 为每个库/包编写测试用例
  • 使用一个好的编辑器(PyCharm是一个很好的Python / iPython)
  • 记录您的API,方法

最后,请记住,有许多方法可以给猫皮肤涂抹,而上述只是我喜欢的一种。 HTH。

答案 2 :(得分:1)

虽然提供的答案涵盖了该主题,但仍然值得一提的是提供数据科学样板项目结构的Cookiecutter

Cookiecutter Data Sciencee

为Python中的项目提供数据科学模板,其中包含用于执行和共享数据科学工作的逻辑,合理标准化且灵活的项目结构。

您的分析不一定是在Python中,但模板确实提供了一些Python样板(例如在src文件夹中,以及文档中的Sphinx文档框架)。但是,没有任何约束力。

项目描述中的以下引用总结得非常好:

  

在创建一个新的Rails项目之前没有人坐下来搞清楚   他们想发表意见的地方;他们只是运行rails new来获得一个   像其他人一样的标准项目骨架。

要求:

  • Python 2.7或3.5
  • cookiecutter Python包&gt; = 1.4.0:pip install cookiecutter

入门

  

启动一个新项目就像在此处运行此命令一样简单   命令行。不需要首先创建一个目录,cookiecutter   会为你做的。

cookiecutter https://github.com/drivendata/cookiecutter-data-science

目录结构

├── LICENSE
├── Makefile           <- Makefile with commands like `make data` or `make train`
├── README.md          <- The top-level README for developers using this project.
├── data
│   ├── external       <- Data from third party sources.
│   ├── interim        <- Intermediate data that has been transformed.
│   ├── processed      <- The final, canonical data sets for modeling.
│   └── raw            <- The original, immutable data dump.
│
├── docs               <- A default Sphinx project; see sphinx-doc.org for details
│
├── models             <- Trained and serialized models, model predictions, or model summaries
│
├── notebooks          <- Jupyter notebooks. Naming convention is a number (for ordering),
│                         the creator's initials, and a short `-` delimited description, e.g.
│                         `1.0-jqp-initial-data-exploration`.
│
├── references         <- Data dictionaries, manuals, and all other explanatory materials.
│
├── reports            <- Generated analysis as HTML, PDF, LaTeX, etc.
│   └── figures        <- Generated graphics and figures to be used in reporting
│
├── requirements.txt   <- The requirements file for reproducing the analysis environment, e.g.
│                         generated with `pip freeze > requirements.txt`
│
├── src                <- Source code for use in this project.
│   ├── __init__.py    <- Makes src a Python module
│   │
│   ├── data           <- Scripts to download or generate data
│   │   └── make_dataset.py
│   │
│   ├── features       <- Scripts to turn raw data into features for modeling
│   │   └── build_features.py
│   │
│   ├── models         <- Scripts to train models and then use trained models to make
│   │   │                 predictions
│   │   ├── predict_model.py
│   │   └── train_model.py
│   │
│   └── visualization  <- Scripts to create exploratory and results-oriented visualizations
│       └── visualize.py
│
└── tox.ini            <- tox file with settings for running tox; see tox.testrun.org

相关:

ProjectTemplate - 为R数据分析提供类似的系统。

答案 3 :(得分:0)

奇怪的是没有人提到这一点。使用 nbdev 写出您的下一个项目。从 docs 开始,我们有

Nbdev 的特点

nbdev 为开发者提供以下工具:

  • 从 Jupyter 笔记本自动生成文档。这些文档可搜索并自动超链接到适当的文档页面,方法是检查您用反引号括起来的关键字。
  • 用于自动发布 PyPI 和 conda 包的实用程序,包括版本号管理。
  • 强大的笔记本和源代码之间的双向同步,允许您根据需要使用 IDE 进行代码导航或快速编辑。
  • 对隐藏/显示单元格的细粒度控制:您可以选择隐藏整个单元格、仅隐藏输出或仅隐藏输入。此外,您可以将单元格嵌入到默认打开或关闭的可折叠元素中。
  • 能够直接在笔记本中编写测试,而无需学习特殊的 API。这些测试与单个 CLI 命令并行执行。您甚至可以定义特定的测试组,这样您就不必总是运行长时间运行的测试。
  • 使用人类可读格式的笔记本合并/冲突解决工具。
  • 持续集成 (CI) 随附 GitHub Actions 开箱即用设置,会自动为您运行测试。即使您不熟悉 CI 或 GitHub Actions,它也会立即开始为您工作,无需任何人工干预。
  • 与用于文档托管的 GitHub Pages 集成:nbdev 允许您使用 GitHub 页面轻松免费托管文档。
  • 按照最佳做法创建 Python 模块,例如使用导出的函数、类和变量自动定义 __all__ (more details)。
  • 数学方程支持与 LaTeX。
  • ……还有更多!有关详细信息,请参阅 Getting Started 部分。

快速入门

  • tutorial
  • 使用 nbdev 的minimal, end-to-end example。我建议您在阅读完教程后复制此示例以巩固您的理解。
  • 使用 nbdev_template
  • 想知道为什么你不早点尝试这个,即使在 1.5 年前就知道了(像我一样)。

如果你喜欢视频

如果视频链接失败,请在 Youtube 上搜索标题以获取它们。 此外,请遵循 volodymyr's answer above

中的所有准则

所有这些评论都是针对笔记本的。 对于任何代码,您必须

  • 编写测试(在编写代码之前或至少之后)
  • 为函数添加文档(最好是 numpy 风格,因为这是一个科学包)
  • 在您发表论文时分享它,这样其他人就不必重新发明轮子(尤其是那些从事物理学工作的人)。

答案 4 :(得分:0)