当前位置: 首页 > 知识库问答 >
问题:

在版本控制下使用IPython/Jupyter笔记本

越英范
2023-03-14

什么是保持IPython笔记本版本控制的好策略?

笔记本格式非常适合进行版本控制:如果想要对笔记本和输出进行版本控制,那么这种方式非常有效。当人们只想对输入进行版本控制时,麻烦就来了,不包括单元输出(也称为“构建产品”),单元输出可以是大的二进制blob,尤其是电影和情节。特别是,我试图找到一个好的工作流程:

  • 允许我在包括或排除输出之间进行选择,
  • 防止我在不需要时意外提交输出,
  • 允许我将输出保存在本地版本中,
  • 允许我使用版本控制系统查看输入的更改(即,如果我只控制输入的版本,但本地文件有输出,则我希望能够查看输入是否已更改(需要提交)。使用版本控制状态命令将始终注册差异,因为本地文件具有输出。)
  • 允许我从更新的干净笔记本更新我的工作笔记本(其中包含输出)。(更新)

如上所述,如果我选择包含输出(例如,当使用nbView时,这是可取的),那么一切都很好。问题是当我不希望版本控制输出时。有一些工具和脚本用于剥离笔记本的输出,但我经常遇到以下问题:

  1. 我不小心用输出提交了一个版本,从而污染了我的存储库。
  2. 我清除输出以使用版本控制,但实际上宁愿将输出保留在本地副本中(例如,有时需要一段时间才能重现)。
  3. 与单元格/所有输出/清除菜单选项相比,一些条带输出的脚本稍微改变了格式,从而在差异中产生了不必要的噪音。这是由一些答案解决的。
  4. 当将更改拉至干净版本的文件时,我需要找到某种方法将这些更改合并到我的工作笔记本中,而不必重新运行所有内容。(更新)

我已经考虑了几个我将在下面讨论的选项,但还没有找到一个好的全面解决方案。完整的解决方案可能需要对IPython进行一些更改,或者可能依赖于一些简单的外部脚本。我目前使用mercurial,但希望有一个同样适用于git的解决方案:理想的解决方案是版本控制不可知。

这个问题已经讨论了很多次,但从用户的角度来看,还没有明确的解决方案。这个问题的答案应该提供明确的战略。如果它需要IPython的最新版本(甚至是开发版本)或易于安装的扩展,这是可以的。

更新:我一直在玩我修改过的笔记本版本,它可以选择使用格雷戈里·克罗斯怀特的建议在每次保存时保存一个。这满足了我的大部分限制,但留下了以下问题未解决:

  1. 这还不是一个标准的解决方案(需要修改ipython源代码。有没有一种方法可以通过简单的扩展实现这种行为?需要某种类型的on save hook。
  • 笔记本运行时,可以使用单元格/All Output/Clear菜单选项删除输出
  • 关于版本控制笔记本格式的思考
  • 977:笔记本功能请求(打开)。
  • 1280:清除-所有保存选项(打开)。(以下是这次讨论。)
  • 3295:自动导出笔记本:仅导出显式标记的单元格(已关闭)。由扩展11解决添加写入和执行魔法(合并)。
  • 1621:清除[]中关于“清除所有输出”(合并)的提示编号。(另见2519(合并)。)
  • 1563:清除输出改进(合并)
  • 3065:笔记本电脑的差异能力(关闭)
  • 3291:添加保存时跳过输出单元格的选项。(关闭)。这似乎极为相关,但最后建议使用“清洁/污迹”过滤器。一个相关的问题:如果您想在运行git diff之前去掉输出,您可以使用什么?似乎没有得到回答
  • 3312:WIP:笔记本保存挂钩(关闭)
  • 3747:ipynb-

共有3个答案

凌和悦
2023-03-14

我基于minrksgist创建了nbstripout,它支持Git和Mercurial(多亏了mforbes)。它既可以在命令行上独立使用,也可以作为筛选器使用,可以通过nbstripout install/nbstripout uninstall轻松(取消)安装到当前存储库中。

从PyPI或简单地获取它

pip install nbstripout
那鹏
2023-03-14

我们有一个合作项目,产品是Jupyter笔记本电脑,在过去的六个月里,我们使用了一种非常有效的方法:我们自动激活保存. py文件,并跟踪. ipynb文件和。py文件。

这样,如果有人想查看/下载最新的笔记本电脑,他们可以通过github或nbview进行,如果有人想查看笔记本代码是如何变化的,他们可以只看. 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\u笔记本\u配置。py文件并重新启动笔记本服务器。

如果您不确定在哪个目录中找到您的jupyter_notebook_config.py文件,您可以键入jupyter--config-dir,如果您在那里找不到文件,您可以通过键入jupyter笔记本来创建它-生成配置。

对于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文件并重新启动笔记本服务器。这些行来自github问题回答@minrk提供的,@dror也将它们包含在他的SO回答中。

对于Ipython 2笔记本服务器,这可以通过以下方式启动服务器来实现:

ipython notebook --script

或者加上一行

c.FileNotebookManager.save_script = True

ipython\u笔记本\u配置。py文件并重新启动笔记本服务器。

如果您不确定要在哪个目录中找到您的ipython\u笔记本\u配置。pyfile,可以键入ipython locate profile default,如果在那里找不到该文件,可以通过键入ipython profile create来创建它。

这是我们在github上使用这种方法的项目:这是一个探索笔记本最近变化的github例子。

我们对此感到非常高兴。

曹景铄
2023-03-14

这是我的git解决方案。它允许你像往常一样添加和提交(和diff):这些操作不会改变你的工作树,同时(重新)运行笔记本不会改变你的git历史。

虽然这可能适用于其他VCS,但我知道它不能满足您的要求(至少VSC不可知性)。尽管如此,它对我来说还是很完美的,尽管它没有什么特别出色的地方,而且许多人可能已经在使用它,但我没有通过谷歌找到关于如何实现它的明确说明。所以它可能对其他人有用。

>

使其可执行(chmod x~/bin/ipynb_output_filter.py

创建文件~/. git属性,内容如下

*.ipynb filter=dropoutput\u ipynb

运行以下命令:

gitcore.attributesfilegit config--globalfilter.dropoutput_ipynb.clean~/bin/ipynb_output_filter.pygit config--globalfilter.dropoutput_ipynb.smudge猫

完成!

限制:

  • 它仅适用于git

我的解决方案反映了这样一个事实,即我个人不喜欢保持生成的东西版本化——请注意,涉及输出的合并几乎肯定会使输出或您的生产力无效,或者两者都无效。

编辑:

>

**.ipynb滤波器=

作为内容。显然,以同样的方式也可以做相反的事情:只为特定的存储库启用过滤。

>

  • 代码现在维护在自己的git repo中

    如果上述说明导致导入,请尝试在脚本路径之前添加“ipython”:

      git config --global filter.dropoutput_ipynb.clean ipython ~/bin/ipynb_output_filter.py
    

    编辑:2016年5月(2017年2月更新):我的脚本有几个备选方案-为了完整起见,这里是我知道的备选方案列表:nbstripout(其他变体)、NBStripe、jq。

  •  类似资料:
    • 笔记本格式非常适合版本控制:如果想要对笔记本和输出进行版本控制,那么这就很好地工作了。当你只想对输入进行版本控制,而不包括单元输出(也就是“构建产品”)时,麻烦就来了,这些单元输出可以是大的二进制blob,特别是对于电影和情节来说。特别是,我正在努力找到一个好的工作流程,它: 允许我在包含或排除输出之间进行选择, 防止我在不想要输出时意外提交输出, 允许我在本地版本中保留输出, 允许我使用版本控制

    • 问题内容: 在IPython / Jupyter Notebook中运行的大多数语言内核的错误报告都指出发生错误的行;但是(至少默认情况下)在笔记本电脑中未显示行号。 是否可以将行号添加到IPython / Jupyter Notebook? 问题答案: -在CodeMirror区域中切换行号。有关其他键盘快捷键,请参见快速帮助。 详细信息- (或)将您带入命令模式,然后按键应切换当前单元格行号的

    • 我回顾了各种相关问题,包括 如何让MathJax在ipython笔记本中启用mhchem扩展 但我不能让它工作。。。 我的测试用例很简单 期待直立的$\pi$,但目前只是'\uppi'回来了。 我已经尝试了以下使用细胞魔法 这会生成

    • 当我打开Jupyter笔记本(以前是IPython)时,它默认为。 我如何将此更改为其他位置?

    • 我正在尝试从git下载Jupyter笔记本。我通过右键单击文件并保存它来下载笔记本。这是一个ipynb文件,但对于它应该包含的内容(114 kb),文件大小对我来说似乎有点大。当我点击Jupyter中的笔记本时,出现以下错误: 无法读取的笔记本:C:\filename。ipynb NotJSONError(“笔记本似乎不是JSON:”\n\n 如何解决此错误,以及如何打开笔记本?

    • 在IPython notebook 3.0版本之前,默认情况下,可以通过将其添加到“.IPython\profile\u default\static\custom\custom.js”(在Windows上)来隐藏笔记本标题: 或者对于Jupyter,“~/. jupyter/定制/custom.js”,将替换为。 也看这个问题 这似乎行不通了。它隐藏了标题,但也在页面的顶部和底部留下了很大的空白