mfo*_*bes 548 version-control ipython jupyter-notebook
将IPython笔记本电脑置于版本控制之下的好策略是什么?
笔记本格式非常适合版本控制:如果想要版本控制笔记本和输出,那么这非常有效.当人们只想对输入进行版本控制时,就会产生烦恼,不包括可能是大型二进制blob的单元格输出(也就是"构建产品"),特别是对于电影和情节.特别是,我试图找到一个良好的工作流程:
如上所述,如果我选择包含输出(例如,在使用nbviewer时这是可取的),那么一切都很好.问题是,当我不想要的版本控制输出.有一些工具和脚本可以剥离笔记本的输出,但我经常会遇到以下问题:
Cell/All Output/Clear菜单选项相比,剥离输出的一些脚本会稍微改变格式,从而在差异中产生不必要的噪声.这可以通过一些答案来解决.我已经考虑过几个选项,我将在下面讨论,但还没有找到一个很好的综合解决方案.完整的解决方案可能需要对IPython进行一些更改,或者可能依赖于一些简单的外部脚本.我目前使用mercurial,但想要一个也适用于git的解决方案:理想的解决方案是版本控制不可知.
这个问题已经多次讨论过,但从用户的角度来看,没有明确或明确的解决方案.这个问题的答案应该提供明确的策略.如果它需要最近的(甚至开发)版本的IPython或一个易于安装的扩展,这很好.
更新:我一直在玩我修改过的笔记本版本,可以选择.clean使用Gregory Crosswhite的建议保存每次保存的版本.这满足了我的大多数约束,但是仍然没有解决以下问题:
.clean文件,然后需要以某种方式集成到我的工作版本中.(当然,我总是可以重新执行笔记本,但这可能会很痛苦,特别是如果某些结果取决于长时间的计算,并行计算等).我还不知道如何解决这个问题.也许涉及像ipycache这样的扩展的工作流可能会起作用,但这似乎有点过于复杂.Cell/All Output/Clear菜单选项删除输出.Pie*_*ton 117
这是我用git的解决方案.它允许您像往常一样添加和提交(和差异):这些操作不会改变您的工作树,同时(重新)运行笔记本不会改变您的git历史记录.
虽然这可能适用于其他VCS,但我知道它不能满足您的要求(至少VSC不可知).尽管如此,它对我来说仍然是完美的,虽然没有什么特别精彩,很多人可能已经使用过它,但我没有找到关于如何通过Google搜索来实现它的明确指示.所以它可能对其他人有用.
~/bin/ipynb_output_filter.py)chmod +x ~/bin/ipynb_output_filter.py)~/.gitattributes使用以下内容创建文件
*.ipynb filter=dropoutput_ipynb
Run Code Online (Sandbox Code Playgroud)运行以下命令:
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
Run Code Online (Sandbox Code Playgroud)完成!
限制:
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
Run Code Online (Sandbox Code Playgroud)编辑:2016年5月(2017年2月更新):我的脚本有几种替代方案 - 为了完整性,这里列出了我所知道的:nbstripout(其他 变种),nbstrip,jq.
Ric*_*ell 58
我们有一个合作项目,产品是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
Run Code Online (Sandbox Code Playgroud)
到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
Run Code Online (Sandbox Code Playgroud)
到ipython_notebook_config.py文件并重新启动笔记本服务器.这些行是来自github问题的答案@minrk提供,而@dror也包含在他的SO答案中.
对于Ipython 2笔记本服务器,可以通过使用以下命令启动服务器来完成:
ipython notebook --script
Run Code Online (Sandbox Code Playgroud)
或者添加该行
c.FileNotebookManager.save_script = True
Run Code Online (Sandbox Code Playgroud)
到ipython_notebook_config.py文件并重新启动笔记本服务器.
如果您不确定在哪个目录中查找ipython_notebook_config.py文件,可以键入ipython locate profile default,如果在那里找不到该文件,可以通过键入来创建ipython profile create.
这是我们在github上使用这种方法的项目:这里是一个探索笔记本最近更改的github示例.
我们对此非常满意.
kyn*_*nan 36
我创建了nbstripout基于MinRKs的gist,它支持Git和Mercurial(感谢mforbes).它既可以在命令行上单独使用,也可以作为过滤器使用,可以通过nbstripout install/ 轻松(非)安装在当前存储库中nbstripout uninstall.
从PyPI或简单地获取它
pip install nbstripout
Run Code Online (Sandbox Code Playgroud)
Spe*_*her 13
这是Cyrille Rossant针对IPython 3.0的新解决方案,它坚持使用markdown文件而不是基于json的ipymd文件:
https://github.com/rossant/ipymd
Wes*_*ner 12
(2017-02)
策略
nbstripout,)nbstripout,)nbconvert到python:name.ipynb.py(nbconvert)nbconvert,ipymd)工具
nbstripout:剥离笔记本电脑的输出
pip install nbstripout; nbstripout installipynb_output_filter:剥离笔记本电脑的输出
ipymd:转换{Jupyter,Markdown,O'Reilly Atlas Markdown,OpenDocument,.py}
nbdime:"用于区分和合并Jupyter笔记本的工具." (2015)
nbdiff:以终端友好的方式比较笔记本电脑
nbmerge:笔记本电脑的三向合并与自动冲突解决
nbdiff-web:向您展示笔记本电脑的丰富渲染差异nbmerge-web:为您提供基于Web的笔记本电脑三向合并工具nbshow:以终端友好的方式呈现单个笔记本nev*_*ves 11
我终于找到了一种高效而简单的方法让Jupyter和Git很好地融合在一起.我还在迈出第一步,但我已经认为它比其他所有复杂的解决方案都要好得多.
Visual Studio Code是Microsoft的一个很酷的开源代码编辑器.它具有出色的Python扩展,现在允许您将Jupyter Notebook作为python代码导入.
将笔记本导入python文件后,所有代码和markdown将一起放在普通的python文件中,注释中带有特殊标记.您可以在下图中看到:
你的python文件只包含笔记本输入单元格的内容.输出将在拆分窗口中生成.你在笔记本中有纯粹的代码,当你执行它时它不会改变.没有与您的代码混合输出.没有奇怪的Json难以理解的格式来分析你的差异.
只需纯Python代码,您可以轻松识别每个差异.
我甚至不需要再对我的.ipynb文件进行版本控制了.我可以放一条*.ipynb线.gitignore.
需要生成笔记本才能发布或与他人分享?没问题,只需单击交互式python窗口中的导出按钮即可
我一直在使用它只有一天,但最后我可以愉快地使用Jupyter与Git.
PS:VSCode代码完成比Jupyter好很多.
在删除笔记本电脑的输出数年之后,我试图提出一个更好的解决方案。现在,我使用Jupytext,这是我设计的Jupyter Notebook和Jupyter Lab的扩展。
Jupytext可以将Jupyter笔记本转换为各种文本格式(脚本,Markdown和R Markdown)。相反。它还提供了将笔记本与以下格式之一配对的选项,并自动同步笔记本的两种表示形式(一个.ipynb和一个.md/.py/.R文件)。
让我解释一下Jupytext如何回答上述问题:
让我可以选择是包含还是排除输出,
该.md/.py/.R文件仅包含输入单元格。您应该始终跟踪该文件。.ipynb仅在要跟踪输出时才对文件进行版本控制。
防止我不想要我的输出,
添加*.ipynb到.gitignore
允许我将输出保持在本地版本中,
输出保留在(本地).ipynb文件中
允许我使用版本控制系统查看何时更改了输入(即,如果仅对版本进行控制,但是本地文件具有输出,那么我希望能够查看输入是否已更改(需要提交) )。由于本地文件具有输出,因此使用version control status命令将始终记录差异。)
.py/.R或.md文件上的差异是您要查找的
允许我从更新的干净笔记本中更新我的工作笔记本(包含输出)。(更新)
拉到.py/.R或.md文件的最新版本,然后在Jupyter(Ctrl + R)中刷新笔记本。您将从文本文件中获取最新的输入单元格,并从.ipynb文件中获取匹配的输出。内核不受影响,这意味着将保留您的局部变量-您可以在离开内核的地方继续工作。
我对Jupytext的爱是可以在您喜欢的IDE中编辑笔记本(以.py/.R或.md文件的形式 )。使用这种方法,重构笔记本变得容易。完成后,您只需要在Jupyter中刷新笔记本即可。
如果想尝试一下:用安装Jupytext,pip install jupytext然后重新启动Jupyter Notebook或Lab编辑器。打开要版本控制的笔记本,然后使用Jupyter笔记本中的Jupytext菜单(或Jupyter Lab中的Jupytext命令)将其与Markdown文件(或脚本)配对。保存您的笔记本,您将获得两个文件:原始文件,以及笔记本的承诺的文本表示形式,非常适合版本控制!.ipynb
对于那些可能感兴趣的人:在命令行上也可以找到Jupytext 。
正如所指出的,已--script被弃用3.x.可以通过应用post-save-hook来使用此方法.特别是,将以下内容添加到ipython_notebook_config.py:
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
Run Code Online (Sandbox Code Playgroud)
代码取自#8009.
与2019年更好的方法相比,上述2016年非常受欢迎的答案是不一致的黑客。
存在几种选择,回答该问题的最佳选择是Jupytext。
它与版本控制一起工作的方式是将.py和.ipynb文件都放入版本控制中。如果需要输入差异,请查看.py;如果需要最新的渲染输出,请查看.ipynb。
值得注意的是:VS Studio,nbconvert,nbdime,氢
我认为,通过更多的工作,VS工作室和/或氢气(或类似产品)将成为该工作流程解决方案中的主导者。
不幸的是,我对Mercurial了解不多,但我可以给你一个与Git一起使用的可能解决方案,希望你能将我的Git命令转换成他们的Mercurial等价物.
对于后台,在Git中,该add命令将对文件所做的更改存储到暂存区域.完成此操作后,Git将忽略对该文件的任何后续更改,除非您告诉它也将其暂存.因此,下面的脚本,对于每个给定的文件,剥离剥离文件的所有outputs和prompt_number sections,阶段,然后恢复原始:
注意:如果运行此操作会收到类似的错误消息ImportError: No module named IPython.nbformat,则使用ipython运行脚本而不是python.
from IPython.nbformat import current
import io
from os import remove, rename
from shutil import copyfile
from subprocess import Popen
from sys import argv
for filename in argv[1:]:
# Backup the current file
backup_filename = filename + ".backup"
copyfile(filename,backup_filename)
try:
# Read in the notebook
with io.open(filename,'r',encoding='utf-8') as f:
notebook = current.reads(f.read(),format="ipynb")
# Strip out all of the output and prompt_number sections
for worksheet in notebook["worksheets"]:
for cell in worksheet["cells"]:
cell.outputs = []
if "prompt_number" in cell:
del cell["prompt_number"]
# Write the stripped file
with io.open(filename, 'w', encoding='utf-8') as f:
current.write(notebook,f,format='ipynb')
# Run git add to stage the non-output changes
print("git add",filename)
Popen(["git","add",filename]).wait()
finally:
# Restore the original file; remove is needed in case
# we are running in windows.
remove(filename)
rename(backup_filename,filename)
Run Code Online (Sandbox Code Playgroud)
一旦脚本在您想要提交其更改的文件上运行,就运行git commit.
我用一种非常务实的方法; 这对于几个笔记本电脑来说很有效.它甚至可以让我"转移"笔记本电脑.它适用于Windows作为Unix/MacOS.
Al认为很简单,就是解决上面的问题......
基本上,你不追踪.ipnyb-files,只有相应的.py-files.
通过使用该选项启动笔记本服务器--script,可以在保存笔记本时自动创建/保存该文件.
那些.py文件确实包含所有输入; 非代码保存到注释中,单元格边框也是如此.可以将这些文件读取/导入(并拖动)到笔记本服务器中以(重新)创建笔记本.只有输出消失了; 直到重新运行.
我个人使用mercurial版本跟踪.py文件; 并使用普通(命令行)命令添加,签入(ect).大多数其他(D)VCS将允许这样做.
现在很容易跟踪历史; 它.py是小的,文本的和简单的差异.有一段时间,我们需要一个克隆(只是分支;在那里启动第二个笔记本 - 服务器),或者旧版本(检出并导入到笔记本服务器中)等.
--script选项)并对其进行版本跟踪.py-file,但不会将其签入.
file@date+rev.py)应该是有用的这将是很多工作来添加; 也许我会这样做一次.到现在为止,我只是手工完成.只是遇到“ jupytext”,它看起来是一个完美的解决方案。它从笔记本生成一个.py文件,然后使两者保持同步。您可以通过.py文件对输入进行版本控制,区分和合并,而不会丢失输出。当您打开笔记本时,它使用.py作为输入单元格,并使用.ipynb作为输出单元。如果要在git中包含输出,则只需添加ipynb。
https://github.com/mwouts/jupytext
我还将向其他人添加建议的https://nbdev.fast.ai/,这是一种最先进的“文学编程环境,正如 Donald Knuth 在 1983 年所设想的那样!”。
它还有一些 git hooks 可以提供一些帮助https://nbdev.fast.ai/#Avoiding-and-handling-git-conflicts以及其他命令,例如:
因此,您还可以在编写库时随时创建文档,例如其中一些文档:
除了第一个链接之外,您还可以在此处观看nbdev 教程的视频。
| 归档时间: |
|
| 查看次数: |
62891 次 |
| 最近记录: |