在版本控制下使用IPython笔记本
在版本控制下保持IPython笔记本的好策略是什么?
笔记本电脑格式非常适合版本控制:如果想要版本控制笔记本电脑和输出,那么这种方式效果很好。 当人们只想控制输入的版本,排除单元格输出(也就是“构建产品”),这可能是一个大的二进制blob,特别是对于电影和剧情,这种烦恼就出现了。 特别是,我试图找到一个好的工作流程:
如前所述,如果我选择包含输出(例如在使用nbviewer时需要),那么一切都很好。 问题是我不想版本控制输出。 有一些工具和脚本用于剥离笔记本的输出,但我经常遇到以下问题:
Cell/All Output/Clear
菜单选项相比,某些剥离输出的脚本会略微改变格式,从而在差异中产生不必要的噪音。 这是通过一些答案解决的。 我已经考虑了几个我将在下面讨论的选项,但还没有找到一个好的综合解决方案。 完整的解决方案可能需要对IPython进行一些更改,或者可能依赖于一些简单的外部脚本。 我目前使用的是mercurial,但想要一个也适用于git的解决方案:理想的解决方案是版本控制不可知的。
这个问题已经被多次讨论过,但从用户的角度来看,并没有明确或明确的解决方案。 这个问题的答案应该提供明确的策略。 如果它需要最新(甚至是开发)版本的IPython或易于安装的扩展,那就好了。
更新:我一直在玩我的修改版笔记本,其任选节省了.clean
版本,每次保存使用格雷戈里Crosswhite的建议。 这满足了我的大部分约束条件,但留下了以下问题:
.clean
文件,然后需要以某种方式集成到我的工作版本中。 (当然,我总是可以重新执行笔记本,但这可能会很痛苦,特别是如果某些结果取决于长计算,并行计算等)。我对如何解决这个问题还没有一个好主意。 也许像ipycache这样的扩展工作流可能会起作用,但这似乎有些复杂。 笔记
删除(剥离)输出
Cell/All Output/Clear
菜单选项来删除输出。 新闻组
问题
拉取请求
这是我用git的解决方案。 它允许你像平常一样添加和提交(和差异):这些操作不会改变你的工作树,并且同时(重新)运行笔记本不会改变你的git历史记录。
尽管这可能适用于其他VCS,但我知道它不能满足您的要求(至少VSC不可知论)。 尽管这对我来说是完美的,虽然没有什么特别的辉煌,而且很多人可能已经在使用它,但我没有找到关于如何通过搜索引擎来实现它的明确说明。 所以对其他人可能有用。
~/bin/ipynb_output_filter.py
) chmod +x ~/bin/ipynb_output_filter.py
) 使用以下内容创建文件~/.gitattributes
*.ipynb filter=dropoutput_ipynb
运行以下命令:
git config --global core.attributesfile ~/.gitattributes
git config --global filter.dropoutput_ipynb.clean ~/bin/ipynb_output_filter.py
git config --global filter.dropoutput_ipynb.smudge cat
完成!
限制:
somebranch
,你做git checkout otherbranch; git checkout somebranch
git checkout otherbranch; git checkout somebranch
,你通常期望工作树不变。 在这里,您将失去两个分支之间信号源不同的笔记本电脑的输出和单元编号。 git commit notebook_file.ipynb
更多的东西,尽管它至少可以让git diff notebook_file.ipynb
免于base64垃圾)。 我的解决方案反映了我个人不喜欢保留生成的版本的事实 - 请注意,执行涉及输出的合并几乎可以保证使输出或您的生产力无效或两者兼而有之。
编辑:
如果您按照我的建议采用解决方案 - 也就是全球范围内的解决方案,那么您会遇到麻烦,因为某些git repo 需要版本输出。 因此,如果您想禁用特定git存储库的输出过滤,只需在其中创建一个文件.git / info / attributes,
**。ipynb filter =
作为内容。 显然,以相同的方式可以做相反的事情:只为特定的存储库启用过滤。
代码现在保存在它自己的git仓库中
如果上述指令导致ImportErrors,请尝试在脚本路径前添加“ipython”:
git config --global filter.dropoutput_ipynb.clean ipython ~/bin/ipynb_output_filter.py
编辑 :2016年5月(2017年2月更新):我的脚本有几种选择 - 为了完整性,这里是我知道的那些列表:nbstripout(其他变体),nbstrip,jq。
我们有一个产品为Jupyter笔记本的合作项目,我们在过去的六个月中采用了一种行之有效的方法:我们激活自动保存.py
文件并跟踪.ipynb
文件和.py
文件。
这样,如果有人想查看/下载最新的笔记本,他们可以通过github或nbviewer来做到这一点,如果有人想看看笔记本代码是如何改变的,他们可以看看.py
文件的变化。
对于Jupyter
笔记本电脑服务器 ,这可以通过添加线路来完成
import os
from subprocess import check_call
def post_save(model, os_path, contents_manager):
"""post-save hook for converting notebooks to .py scripts"""
if model['type'] != 'notebook':
return # only do this for notebooks
d, fname = os.path.split(os_path)
check_call(['jupyter', 'nbconvert', '--to', 'script', fname], cwd=d)
c.FileContentsManager.post_save_hook = post_save
到jupyter_notebook_config.py
文件并重新启动笔记本服务器。
如果您不确定在哪个目录中找到您的jupyter_notebook_config.py
文件,可以键入jupyter --config-dir
,如果您没有在其中找到该文件,可以通过键入jupyter notebook --generate-config
。
对于Ipython 3
笔记本服务器 ,可以通过添加这些行来完成
import os
from subprocess import check_call
def post_save(model, os_path, contents_manager):
"""post-save hook for converting notebooks to .py scripts"""
if model['type'] != 'notebook':
return # only do this for notebooks
d, fname = os.path.split(os_path)
check_call(['ipython', 'nbconvert', '--to', 'script', fname], cwd=d)
c.FileContentsManager.post_save_hook = post_save
到ipython_notebook_config.py
文件并重新启动笔记本服务器。 这些行来自@minrk提供的github问题答案,@dror也包含在他的SO答案中。
对于Ipython 2
笔记本服务器 ,这可以通过使用以下命令启动服务器来完成:
ipython notebook --script
或者通过添加该行
c.FileNotebookManager.save_script = True
到ipython_notebook_config.py
文件并重新启动笔记本服务器。
如果您不确定在哪个目录中找到您的ipython_notebook_config.py
文件,则可以键入ipython locate profile default
,如果您没有在其中找到该文件,可以通过键入ipython profile create
来创建它。
这是我们在github上使用这种方法的项目:这里有一个探索笔记本最近变化的github例子。
我们对此非常满意。
我已经创建nbstripout
,基于MinRKs要点,同时支持Git和水银(感谢mforbes)。 它可以在命令行上单独使用,也可以作为过滤器使用,通过nbstripout install
/ nbstripout uninstall
可轻松(未)安装到当前存储库中。
从PyPI或简单地获取它
pip install nbstripout
链接地址: http://www.djcxy.com/p/35487.html