バージョン管理下でIPythonノートブックを使用する


569

IPythonノートブックをバージョン管理下に置くための良い戦略は何ですか?

ノートブックの形式はバージョン管理に非常に適しています。ノートブックと出力をバージョン管理したい場合、これは非常にうまく機能します。特に映画やプロットの場合、大きなバイナリblobになる可能性のあるセル出力(別名「ビルドプロダクト」)を除いて、入力のバージョン管理のみを行いたい場合に問題が発生します。特に、次のような優れたワークフローを見つけようとしています。

  • 出力を含めるか除外するかを選択できます
  • 不要な出力を誤ってコミットするのを防ぎます。
  • ローカルバージョンで出力を保持できます。
  • バージョン管理システムを使用して入力に変更があるかどうかを確認できます(つまり、バージョン管理のみで入力がローカルファイルに出力がある場合、入力が変更されたかどうかを確認できます(コミットが必要) )ローカルファイルには出力があるため、バージョン管理ステータスコマンドを使用すると、常に差異が登録されます。
  • 更新されたクリーンなノートブックから作業用ノートブック(出力を含む)を更新できます。(更新)

前述のように、出力を含めることを選択した場合(たとえば、nbviewerを使用する場合に望ましい)、すべて問題ありません。問題は、出力をバージョン管理したくない場合です。ノートブックの出力を取り除くためのツールとスクリプトはいくつかありますが、次の問題が頻繁に発生します。

  1. 出力でバージョンを誤ってコミットしてしまい、リポジトリが汚染されます。
  2. 私はバージョン管理を使用するために出力をクリアしますが、実際には出力をローカルコピーに保持します(たとえば、再現に時間がかかる場合があります)。
  3. 出力を取り除くスクリプトの一部は、Cell/All Output/Clearメニューオプションと比較して形式をわずかに変更するため、差分に不要なノイズが発生します。これはいくつかの回答によって解決されます。
  4. ファイルのクリーンバージョンへの変更をプルするとき、すべてを再実行せずに、作業ノートブックにそれらの変更を組み込む方法を見つける必要があります。 (更新)

以下で説明するいくつかのオプションを検討しましたが、まだ包括的な解決策を見つけるには至っていません。完全なソリューションでは、IPythonにいくつかの変更が必要になる場合や、いくつかの単純な外部スクリプトに依存する場合があります。私は現在mercurialを使用していますが、gitでも機能するソリューションが欲しいのですが、理想的なソリューションはバージョン管理にとらわれません。

この問題は何度も議論されてきましたが、ユーザーの観点からの決定的または明確な解決策はありません。この質問への答えは、決定的な戦略を提供する必要があります。IPythonの最新(開発)バージョンまたは簡単にインストールできる拡張機能が必要な場合は問題ありません。

更新:私はオプションでGregory Crosswhiteの提案を使用して保存するたびにバージョンを保存するように変更したノートブックバージョンで遊んでいます。これは私の制約のほとんどを満たしますが、次の未解決のままになります。.clean

  1. これはまだ標準的なソリューションではありません(ipythonソースの変更が必要です。単純な拡張機能でこの動作を実現する方法はありますか?何らかの保存フックが必要です。
  2. 現在のワークフローで私が抱えている問題は、変更のプルです。これらは.cleanファイルに入ってきて、どういうわけか私の作業バージョンに統合する必要があります。(もちろん、いつでもノートブックを再実行できますが、特に結果の一部が長時間の計算や並列計算などに依存している場合は、これは苦痛になる可能性があります。)これを解決する方法についてはまだよくわかりません。おそらくipycacheのような拡張を含むワークフローは機能するかもしれませんが、それは少し複雑すぎるようです。

ノート

出力の削除(ストリップ)

  • ノートブックの実行中に、Cell/All Output/Clearメニューオプションを使用して出力を削除できます。
  • 出力を削除するスクリプトnbstripout.pyなど、出力を削除するためのスクリプトがいくつかありますが、ノートブックインターフェイスを使用する場合と同じ出力は生成されません。これは最終的にipython / nbconvertリポジトリに含まれていましたが、変更がipython / ipythonに含まれるようになったとのことでクローズされましたが、対応する機能はまだ含まれていないようです。 (更新)そうは言っても、Gregory Crosswhiteのソリューションは、ipython / nbconvertを呼び出さなくても、これがかなり簡単であることを示していますなので、このアプローチは、適切に接続できる場合はおそらく機能します。(ただし、各バージョン管理システムに接続するのは良い考えではないようです。ノートブックメカニズムに接続する必要があります。)

ニュースグループ

問題

プルリクエスト


github.com/ipython/ipythonに問題として追加するか、この目標をさらに進めるのに役立つプルリクエストを送信するのは素晴らしいことのように思えます。
カイルケリー2013

4
出力を削除するための作業スクリプトを作成したら、Gitの "clean"フィルターを使用して、コミットする前にそれを自動的に適用できます(clean / smudgeフィルターを参照)。
Matthias

1
@foobarbecue質問には不十分な回避策が含まれています。それぞれに少なくとも1つの制限があります。PR 4175が統合されたので、おそらく完全なソリューションを定式化できますが、これはまだ実行する必要があります。時間があれば、その間に他の誰かが満足のいく解決策を提供できない場合は、(回答として)すぐに行います。
mforbes 2013年

1
@saroele私はまだ推奨される解決策を見つけていません:私は--scriptオプションで行くつもりでしたが、それは削除されました。保存後のフックが実装される(計画されている)まで待っています。その時点で、いくつかの手法を組み合わせて許容できるソリューションを提供できると思います。
mforbes 2014年

1
@mforbesそのPRはコメントの数日後にマージされたようです。あなたまたは私より知識のある誰かが、新機能の使用方法を示す回答をここに投稿できますか?
神戸ジョン2014

回答:


124

これがgitを使った私の解決策です。通常どおり、追加とコミット(および差分)を実行できます。これらの操作は作業ツリーを変更せず、同時にノートブックを(再)実行してもgit履歴は変更されません。

これはおそらく他のVCSに適合させることができますが、あなたの要件(少なくともVSCの不可知性)を満たさないことは知っています。それでも、それは私にとっては完璧であり、特に優れたものではなく、おそらく多くの人がすでにそれを使用していると思いますが、グーグルで実装する方法についての明確な指示は見つかりませんでした。ですから、他の人にも役立つかもしれません。

  1. このコンテンツを含むファイルをどこかに保存します(以下では、仮定します~/bin/ipynb_output_filter.py
  2. 実行可能にする(chmod +x ~/bin/ipynb_output_filter.py
  3. ~/.gitattributes次の内容のファイルを作成します

    *.ipynb    filter=dropoutput_ipynb
    
  4. 次のコマンドを実行します。

    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
    

できた!

制限:

  • gitでのみ機能します
  • あなたがブランチである場合にはgitに、somebranchそしてあなたがgit checkout otherbranch; git checkout somebranch、あなたは通常、作業ツリーは変わらないことを期待しています。ここでは代わりに、2つのブランチ間でソースが異なるノートブックの出力とセル番号が失われます。
  • より一般的には、グレゴリーのソリューションと同様に、出力はまったくバージョン管理されません。チェックアウトに関連する何かを行うたびにそれを破棄するだけでなく、別のファイルに保存することでアプローチを変更できます(ただし、上記のコードが実行される時点では、コミットIDは不明であることに注意してください)。可能であればそれらをバージョン管理します(git commit notebook_file.ipynbただし、少なくともgit diff notebook_file.ipynbbase64ガベージから解放されますが、これには以外のものが必要になることに注意してください)。
  • とは言っても、何らかの出力を含むプルコード(つまり、このアプローチを使用していない誰かによってコミットされたコード)を実行すると、出力は正常にチェックアウトされます。ローカルで生成された出力のみが失われます。

私の解決策は、個人的に生成されたものをバージョン管理したままにしたくないという事実を反映しています-出力を含むマージを実行すると、出力または生産性、あるいはその両方が無効になることがほぼ保証されます。

編集:

  • 私が提案したように、つまりグローバルにソリューションを採用すると、出力をバージョン管理したい gitリポジトリの場合に問題が発生します。したがって、特定のgitリポジトリの出力フィルタリングを無効にする場合は、その中にファイル.git / info / attributesを作成します

    **。ipynbフィルター=

コンテンツとして。明らかに、同じように反対のことを行うことができます。特定のリポジトリに対してのみフィルタリングを有効にします。

  • コードは独自のgitリポジトリで維持されるようになりました

  • 上記の手順でImportErrorsが発生する場合は、スクリプトのパスの前に「ipython」を追加してみてください。

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

EDIT:2016年5月には、(2017年2月更新):私のスクリプトにいくつかの選択肢がある-完全を期すために、ここで私が知っている人のリストです:nbstripout他の 変種)、nbstripJQは


2
プルした変更を組み込む問題にどのように対処しますか?すべての出力を再生成する必要があるだけで生きていますか?(私はこれが2番目の制限の現れだと思います。)
mforbes

1
@zhermes:この拡張バージョンは問題ないはずです
Pietro Battiston

1
このgitフィルターメソッドを外部のdiffツールで使用する方法はありますか?通常のコマンドラインツールを使用している場合はフィルターが適用されますが、差分ツールとしてmeldを使用している場合は適用されません。stackoverflow.com/q/30329615/578770
FA

1
避けるためにImportError、私はipythonを使用して実行するには、上記には、ALTER持っていた:git config --global filter.dropoutput_ipynb.clean ipython ~/bin/ipynb_output_filter.py
chris838

1
素晴らしい解決策Pietro、ありがとう:)私の場合、スクリプトを使用するときに2つの点を変更しました~/.gitattributes。 )正規表現をと定義しました。workdir/**/*.ipynb filter=dropoutput_ipynbほとんどのノートブックをworkdir / =>に配置し、出力を使用してノートブックをプッシュし、Githubでブックマーク可能なレンダリングを楽​​しみたい場合は、そのフォルダーの外に置きます。
2015

63

私たちは、製品がJupyter Notebooksである共同プロジェクトを行っており、過去6か月間、優れた方法でアプローチしています。.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ファイルやノート、サーバーを再起動します。これらの行は、提供されたgithubの問題の回答@minrkからのものであり、@ 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の例

私たちはこれにとても満足しています。


1
使用--scriptが実際に機能しているという追加の証拠をありがとう。これの問題は、画像が保持されている場合、実際のノートブックが巨大になる可能性があることです。この方法に沿った理想的なソリューションは、最新の完全なノートブックのみを追跡するためにgit-annexのようなものを使用する可能性があります。
mforbes 2014

Ipython 3.xでは、これ--scriptは非推奨です。ipython.org/ipython-doc/3/whatsnew/version3.html
Dror

@drorのおかげで、minrkのipython 3.xソリューションを提供するように回答を更新しました。
リッチシグネル2015年

10
更新:このソリューションは、iPythonバージョン4では機能しません。これは、iPythonからのJupyterの「ビッグスプリット」が原因です。このソリューションをバージョン4に調整するには、コマンドjupyter notebook --generate-configを使用して構成ファイルを作成します。このコマンドjupyter --config-dirは、設定ファイルが含まれているディレクトリを見つけます。また、@ Richによって指定されたコードスニペットをという名前のファイルに追加する必要がありますjupyter_notebook_config.py。残りは以前と同じように動作します。
メビウス餃子

2
@mobiusdumplingによるポイントに加えて、をに置き換えます。そうしないcheck_call(['ipython'check_call(['jupyter'ipython nbconvert非推奨の警告が表示されるので、jupyter nbconvert代わりに使用する必要があります。(Jupyter v4.1.0、iPython v4.1.2)
cutculus

36

私は、GitとMercurialの両方をサポートするMinRKs gistnbstripoutに基づいて作成しました(mforbesに感謝)。これは、コマンドラインでスタンドアロンで使用するか、または/ 経由で現在のリポジトリに簡単に(アン)インストールできるフィルターとして使用することを目的としています。nbstripout installnbstripout uninstall

PyPIから、または単に入手する

pip install nbstripout

上記の保存後フックを使用して自動的に作成された.ipynbと対応する.pyの両方を保持するワークフローを検討しています。差分に.pyを使用したい-nbstripoutがセル実行カウンターから.pyファイルをクリアできるように(#In [1]がIn [*]に変更)、差分が乱雑にならないようにしたり、それを行うための簡単なスクリプトを作成しますか?
KrzysztofSłowiński2017

1
@KrzysztofSłowińskiいいえ、nbstripoutNotebookのJSON形式に依存しているため、この使用例は簡単にはサポートされません。ユースケースに特化したスクリプトを記述する方がよいでしょう。
kynan

13

以下は、IPython 3.0向けのCyrille Rossantによる新しいソリューションです。これは、jsonベースのipymdファイルではなく、マークダウンファイルに持続します。

https://github.com/rossant/ipymd


Jupyterはまだサポートされていないようです。
K.-Michael Aye

最新のJupyterでipymdを正常に使用しています-特定の問題やエラーメッセージは表示されますか?
キリルロサント2016

13

ノートブックの出力を数年削除した後、私はより良い解決策を考え出そうとしました。私は今、私が設計したJupyter NotebookとJupyter Labの両方の拡張であるJupytextを使用しています。

Jupytextは、Jupyterノートブックをさまざまなテキスト形式(スクリプト、Markdown、R Markdown)に変換できます。そして逆に。また、ノートブックをこれらの形式のいずれかにペアリングし、ノートブックの2つの表現(ファイル.ipynb.md/.py/.Rファイル)を自動的に同期するオプションも提供します。

Jupytextが上記の質問にどのように答えるかを説明しましょう:

出力を含めるか除外するかを選択できます

.md/.py/.Rファイルには、入力セルのみが含まれています。このファイルは常に追跡する必要があります。.ipynb出力を追跡する場合にのみ、ファイルにバージョンを付けます。

不要な出力を誤ってコミットするのを防ぎます。

追加*.ipynbします.gitignore

ローカルバージョンで出力を保持できます。

出力は(ローカル).ipynbファイルに保存されます

バージョン管理システムを使用して入力に変更があるかどうかを確認できます(つまり、バージョン管理のみで入力がローカルファイルに出力がある場合、入力が変更されたかどうかを確認できます(コミットが必要) )ローカルファイルには出力があるため、バージョン管理ステータスコマンドを使用すると、常に差異が登録されます。

.py/.Rまたは.mdファイルの差分はあなたが探しているものです

更新されたクリーンなノートブックから作業用ノートブック(出力を含む)を更新できます。(更新)

.py/.Rまたは.mdファイルの最新リビジョンをプルし、Jupyterでノートブックを更新します(Ctrl + R)。ファイルからの一致する出力とともに、テキストファイルから最新の入力セルを取得し.ipynbます。カーネルは影響を受けません。つまり、ローカル変数は保持されます。残した場所から作業を続けることができます。

Jupytextで気に入っている点は、ノートブック( .py/.Rまたは.mdファイルの形式)をお気に入りのIDEで編集できることです。このアプローチにより、ノートブックのリファクタリングが簡単になります。完了したら、Jupyterでノートブックを更新する必要があります。

試してみたい場合:Jupytextをインストールしpip install jupytext、Jupyter NotebookまたはLabエディターを再起動します。バージョン管理するノートブックを開き、JupyterノートブックのJupytextメニュー(またはJupyter LabのJupytextコマンド)を使用て、Markdownファイル(またはスクリプト)とペアリングします。ノートブックを保存すると、2つのファイルが得られます。元のと、ノートブックの約束されたテキスト表現であり、バージョン管理に最適です。.ipynb

興味があるかもしれません:Jupytextはコマンドラインでも利用できます。


13

更新: Visual Studio CodeでJupyter Notebookファイルを直接編集できるようになりました。ノートブックまたは変換されたpythonファイルの編集を選択できます。

最終的に、JupyterとGitをうまく連携させる生産的で簡単な方法を見つけました。私はまだ最初の段階ですが、他のすべての複雑なソリューションよりもはるかに優れているとすでに思っています。

Visual Studio Codeは、Microsoftのクールでオープンソースのコードエディターです。これは、Jupyter NotebookをPythonコードとしてインポートできる優れたPython拡張機能を備えています。これで、Jupyter Notebooksを直接編集することもできます。

ノートブックをpythonファイルにインポートすると、すべてのコードとマークダウンが通常のpythonファイルにまとめられ、コメントに特別なマーカーが付きます。下の画像で確認できます。

ノートブックをpythonに変換したVSCodeエディター

Pythonファイルには、ノートブックの入力セルの内容のみが含まれています。出力は分割ウィンドウで生成されます。ノートブックに純粋なコードがあり、実行しただけでは変更されません。コードとの混合出力はありません。差分を分析するための奇妙なJSON不可解な形式はありません。

すべてのdiffを簡単に識別できる純粋なpythonコード。

.ipynbファイルをバージョン管理する必要はもうありません。で*.ipynb行を入れることができ.gitignoreます。

誰かと公開または共有するためにノートブックを生成する必要がありますか?問題ありません。対話型のpythonウィンドウでエクスポートボタンクリックするだけです。

PythonファイルをNotebook形式にエクスポートする

ノートブックを直接編集している場合は、アイコンが表示されますConvert and save to a python scriptVisual Studio CodeのJupyterアイコン

以下は、Visual Studio Code内のノートブックのスクリーンショットです。

VSCode内でのノートブックの編集

私はそれを1日間だけ使用していますが、最終的にはGupでJupyterを楽しく使用できます。

PS:VSCodeコード補完はJupyterよりもはるかに優れています。


12

(2017年2月)

戦略

  • on_commit():
    • 出力を取り除く> name.ipynb(nbstripout、)
    • 出力を取り除く> name.clean.ipynb(nbstripout、)
    • 常にnbconvertpythonに:name.ipynb.py(nbconvert
    • 常にマークダウンに変換:name.ipynb.md(nbconvertipymd
  • vcs.configure():
    • git difftool、mergetool:nbdimeのnbdiffおよびnbmerge

ツール

  • nbstripout:ノートブックから出力を取り除きます
  • ipynb_output_filter:ノートブックから出力を取り除きます
  • ipymd:{Jupyter、Markdown、O'Reilly Atlas Markdown、OpenDocument、.py}間の変換
  • nbdime:「Jupyterノートブックの差分とマージのためのツール。」(2015)
    • src:https : //github.com/jupyter/nbdime
    • docs:http : //nbdime.readthedocs.io/
      • nbdiff:端末に適した方法でノートブックを比較する
        • nbdime nbdiffはgit diffツールとして機能しますhttps : //nbdime.readthedocs.io/en/latest/#git-integration-quickstart
      • nbmerge:自動競合解決によるノートブックの3者間マージ
        • nbdime nbmergeはgitマージツールとして機能します
      • nbdiff-web:レンダリングされたノートブックのリッチな差分を表示します
      • nbmerge-web:ノートブック用のWebベースの3者間マージツールを提供します
      • nbshow:端末に適した方法で1つのノートブックを提示する

11

上記の非常に人気のある2016年の回答は、2019年にこれを行うためのより良い方法と比較して、一貫性のないハッキングです。

いくつかのオプションが存在しますが、質問に答える最良の方法はJupytextです。

Jupytext

キャッチJupytext上に向けて、データ・サイエンスの記事を

バージョン管理で機能する方法は、.pyファイルと.ipynbファイルの両方をバージョン管理に配置することです。入力の差分が必要な場合は.pyを、最新のレンダリング出力が必要な場合は.ipynbを確認してください。

注目すべき言及:VS studio、nbconvert、nbdime、水素

もう少し作業が進むと、VSスタジオや水素(または同様の)がこのワークフローのソリューションの主要なプレーヤーになると思います。


9

完璧なソリューションのように見える「jupytext」に出くわすだけです。ノートブックから.pyファイルを生成し、両方の同期を維持します。出力を失うことなく、.pyファイルを介して入力のバージョン管理、比較、マージを行うことができます。ノートブックを開くと、入力セルには.pyが使用され、出力には.ipynbが使用されます。そして、出力をgitに含めたい場合は、ipynbを追加するだけです。

https://github.com/mwouts/jupytext


9

ノートブックのバージョン管理を処理するための非常に多くの戦略とツールが存在するため、適切な戦略を選択するためのフロー図を作成してみました(2019年4月作成)

バージョン管理戦略を選択する決定フロー


8

で指摘されているように、--scriptはで非推奨になってい3.xます。このアプローチは、保存後フックを適用することで使用できます。特に、以下をに追加します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

コードは#8009から取得されます。


保存後フックの使用を実演していただきありがとうございます。残念ながら、他で述べたように、.pyファイルからノートブックに戻るのは問題が多いため、残念ながらこれは完全な解決策ではありません。(私は一種の願いのそれはそれはデフに非常にいいですたとして.py代わりにノートPCのファイルおそらく新しい。ノートブックのdiff機能が有用であろう。
mforbes

1
ありがとう!--scriptバージョン管理に関係なく、このトリックを使用して動作を再現しています。最初はいくつかの問題があったので、誰かを少し時間を節約できるように:1)ipython_notebook_config.pyがプロファイルフォルダーにない場合は、実行ipython profile createして生成します。2)post-save-hookが無視されているように見える場合、ipythonを実行し--debugて問題を診断します。3)スクリプトがエラーで失敗した場合ImportError: No module named mistune-単純なminstueをインストールしますpip install mistune
Joe

7

残念ながら、私はMercurialについてはあまり知りませんが、私のGitコマンドをMercurialの同等のコマンドに変換できることを期待して、Gitで機能する可能なソリューションを提供できます。

バックグラウンドでは、Gitのaddコマンドにより、ファイルに加えられた変更がステージング領域に保存されます。これを行うと、ファイルへの以降の変更は、ステージングするように指示しない限り、Gitによって無視されます。したがって、次のスクリプトは、指定されたファイルごとにすべてのoutputsandを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)

変更をコミットしたいファイルに対してスクリプトを実行したら、を実行しますgit commit


提案をありがとう。Mercurialには、実際にはgitのようなステージング領域はありません(ただし、この目的のためにmercurialキューを使用できます)。それまでの間、このコードを.clean拡張機能付きのクリーンバージョンを保存する保存フックに追加してみました。残念ながら、IPython直接変更せずにこれを行う方法はわかりませんでした(ただし、この変更は非常に簡単なものでした)。私はしばらくこれで遊んで、それが私のニーズのすべてに合うかどうかを確認します。
mforbes 2013年

6

私は非常に実用的なアプローチを使用しています。これは、いくつかの側面で、いくつかのノートブックに適しています。また、ノートブックを「移動」することもできます。WindowsでもUnix / MacOSでも動作します。
アルはそれが簡単だと思った、上記の問題を解決することです...

概念

基本的に、-files 追跡せ.ipnyb、対応する.py-files のみを追跡します。
開始することにより、ノートブック、サーバー--scriptオプションを、そのファイルは自動的にノートブックを保存するときに保存/作成されます。

これらの.pyファイルにはすべての入力が含まれています。非コードは、セルの境界線と同様にコメントに保存されます。これらのファイルは、ノートブックサーバーに読み取り/インポート(およびドラッグ)して、ノートブックを(再)作成できます。出力のみが失われます。再実行されるまで。

個人的に私はファイルをバージョン追跡するために水銀を使用してい.pyます。通常の(コマンドライン)コマンドを使用して、追加、チェックイン(ect)します。他のほとんどの(D)VCSはこれを許可します。

簡単に履歴を追跡できます。.pyデフに、小さなテキストおよび簡単です。たまには、クローン(ブランチだけ、2番目のノートブックサーバーをそこから開始)、または古いバージョン(チェックアウトしてノートブックサーバーにインポート)などが必要です。

ヒントとコツ

  • * .ipynbを ' .hgignore 'に追加すると、Mercurialはこれらのファイルを無視できることを認識します。
  • --scriptオプションで)サーバーを起動してバージョン追跡を行う(bash)スクリプトを作成します
  • ノートブックを保存すると.py-file は保存されますが、チェックインはされませ
    • これは欠点です。
    • これは機能でもあります:リポジトリ履歴をクラスター化せずにノートブックを保存(後で続行)できます。

願い

  • ノートブックのダッシュボードにチェックイン/追加/その他のボタンがあると便利です
  • (例として)へのチェックアウトfile@date+rev.pyは役に立ちます。それを追加するのは大変な作業になります。そして多分私は一度そうします。今までは手作業でやっていました。

.pyファイルからノートブックに戻るにはどうすればよいですか?私はこのアプローチが好きですが、.ipynb-> .py-> .ipynbは潜在的に損失が多いため、これを真剣に検討しませんでした。
mforbes 14

これは簡単です。たとえば、ノートブックダッシュボードにドロップしてロードします。「出力データ」を除いて、失われるものは何もない
Albert

それが本当なら、私はこれはアイデアに近いと思いますが、IPythonがフォーマット.pyから.ipynbフォーマットへの移行でデータを完全に保存することを約束しなかったことを思い出しているようです。これには問題があります。おそらくこれが完全なソリューションの基礎を形成するでしょう。
mforbes 2014

.pyファイルからファイルへの変換が困難.ipynbです。 nbconvertはまだこれをサポートしていないようですipython notebook。手動で実行しているため、ノートブックダッシュボードはありません。この逆変換を実装する方法に関する一般的な提案はありますか?
mforbes 2014

確かに、.pyノートブックへの変換は、往復を意図したものではありません。したがって、これは実際には一般的な解決策にはなりませんが、うまくいくのは素晴らしいことです。
holdenweb 2014

3

次のようなUnicode解析エラーが発生した場合、Pietro Battistonによる優れたスクリプトをフォローアップします。

Traceback (most recent call last):
  File "/Users/kwisatz/bin/ipynb_output_filter.py", line 33, in <module>
write(json_in, sys.stdout, NO_CONVERT)
  File "/Users/kwisatz/anaconda/lib/python2.7/site-packages/IPython/nbformat/__init__.py", line 161, in write
fp.write(s)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2014' in position 11549: ordinal not in range(128)

スクリプトの最初に追加できます:

reload(sys)
sys.setdefaultencoding('utf8')

3

この問題を解決するpythonパッケージを作成しました

https://github.com/brookisme/gitnb

これは、gitリポジトリ内のノートブックを追跡/更新/比較するためのgit風の構文を備えたCLIを提供します。

ここに例があります

# add a notebook to be tracked
gitnb add SomeNotebook.ipynb

# check the changes before commiting
gitnb diff SomeNotebook.ipynb

# commit your changes (to your git repo)
gitnb commit -am "I fixed a bug"

「gitnb commit」を使用している最後のステップがgitリポジトリにコミットしていることに注意してください。その本質的にはラッパー

# get the latest changes from your python notebooks
gitnb update

# commit your changes ** this time with the native git commit **
git commit -am "I fixed a bug"

さらにいくつかの方法があり、各段階で多かれ少なかれユーザー入力を必要とするように構成できますが、それは一般的な考え方です。


3

いろいろ調べてみたところ、Jupyterのドキュメントに、この比較的単純なpre-saveフックがついに見つかりました。セル出力データを取り除きます。それをjupyter_notebook_config.pyファイルに貼り付ける必要があります(手順については以下を参照)。

def scrub_output_pre_save(model, **kwargs):
    """scrub output before saving notebooks"""
    # only run on notebooks
    if model['type'] != 'notebook':
        return
    # only run on nbformat v4
    if model['content']['nbformat'] != 4:
        return

    for cell in model['content']['cells']:
        if cell['cell_type'] != 'code':
            continue
        cell['outputs'] = []
        cell['execution_count'] = None
        # Added by binaryfunt:
        if 'collapsed' in cell['metadata']:
            cell['metadata'].pop('collapsed', 0)

c.FileContentsManager.pre_save_hook = scrub_output_pre_save

リッチSignellの答え

jupyter_notebook_config.pyファイルを検索するディレクトリがわからない場合は、jupyter --config-dir[into command prompt / terminal]と入力できますjupyter notebook --generate-config。ファイルが見つからない場合は、と入力して作成できます。


1
私は、このソリューションは、保存することはないことに注意してくださいう任意のディスクに出力をし、バージョン管理の問題にある程度独立しています。
bdforbes 2017

2

私はAlbert&Richがやったことをしました-.ipynbファイルをバージョン管理しないでください(これらには画像が含まれる可能性があり、面倒になります)。代わりに、常に実行するipython notebook --scriptc.FileNotebookManager.save_script = True、設定ファイルに入れて、.pyノートブックを保存すると常に(バージョン管理可能な)ファイルが作成されるようにします。

ノートブックを再生成するには(リポをチェックアウトするかブランチを切り替えた後)、ノートブックを保存するディレクトリにスクリプトpy_file_to_notebooks.pyを置きます。

ここで、リポジトリをチェックアウトした後、実行python py_file_to_notebooks.pyしてipynbファイルを生成します。ブランチを切り替えた後python py_file_to_notebooks.py -ov、既存のipynbファイルを上書きするために実行する必要がある場合があります。

安全の*.ipynbために、.gitignoreファイルにも追加すること をお勧めします。

編集:(A)ブランチをチェックアウトするたびにpyファイルからノートブックを再生成する必要があり、(B)ノートブックのマークダウンなど、失うものがあるので、私はこれをもう行いません。代わりに、gitフィルターを使用してノートブックから出力を取り除きます。これを行う方法についての議論はここにあります


私はこのアイデアが好きでしたが、テストの結果、.pyファイルからへの変換.ipynbは、特にコンバータがまだないバージョン4のノートブックでは特に問題があることがわかりました。現在、v3インポーターを使用してからv4に変換する必要があります。この複雑な移動について少し心配です。また、.pyノートブックが主にJuliaコードである場合、ファイルはあまり良い選択ではありません!最後に、--scriptは非推奨であるため、フックを使用する方法だと思います。
mforbes 2015

あなたのリンクのgitフィルターソリューションは良いです、あなたはここから答えをここにコピーする必要があります:-)
mcarans

2

ここでの説明に従って、現在の最良の解決策のように見えますが、コミット時にipynbファイルから出力を自動的に取り除くgitフィルターを作成することです。

これを機能させるために私がしたことは次のとおりです(その議論からコピー)。

:私はあなたが最新のIPythonインポートすることができないとき有益なエラーを与えることを少しcfriedlineのnbstripoutファイルを修正 https://github.com/petered/plato/blob/fb2f4e252f50c79768920d0e47b870a8d799e92b/notebooks/config/strip_notebook_outputを することができます、そして、私のレポにこれを追加しましたで言う./relative/path/to/strip_notebook_output

また、以下を含む.gitattributesファイルをリポのルートに追加しました。

*.ipynb filter=stripoutput

そしてsetup_git_filters.sh収容を作成しました

git config filter.stripoutput.clean "$(git rev-parse --show-toplevel)/relative/path/to/strip_notebook_output" 
git config filter.stripoutput.smudge cat
git config filter.stripoutput.required true

そして走ったsource setup_git_filters.sh。凝った$(git rev-parse ...)は、任意の(Unix)マシンでリポジトリのローカルパスを見つけることです。


1

このjupyter拡張機能により、ユーザーはjupyterノートブックを直接githubにプッシュできます。

こちらをご覧ください

https://github.com/sat28/githubcommit


これが何をするか説明できますか?機能性は特に明確ではありません。
Alex Monras

これは、直接あなたがコミットメッセージを使用してGitHubのレポにノートPCをプッシュすることができ、そこからjupyterノートブックにボタンを追加します@AlexMonras
座っ

1

これは2020年4月で、Jupyterノートブックのバージョン管理には多くの戦略とツールがあります。ここでは、使用できるすべてのツールの概要を示します。

  • nbdime-ローカルでのノートブックの比較とマージに最適

  • nbstripout-各コミットの前にノートブックの出力を自動的に削除するgitフィルター

  • jupytext-各ノートブックに同期された.pyコンパニオンファイルを保持します。コミットするのは.pyファイルのみ

  • nbconvert-ノートブックをpythonスクリプトまたはHTML(またはその両方)に変換し、これらの代替ファイルタイプをコミットする

  • ReviewNB -GitHubでのコミットまたはプルリクエストのノートブックの差分を(出力とともに)表示します。ノートブックのセルにコメントを書き込んで、変更について話し合うこともできます(下のスクリーンショット)。

ここに画像の説明を入力してください

免責事項:私はReviewNBを構築しました。


0

以下の投稿で説明されている、ノートブックの出力を保持する必要のあるアイデアについては、生成に時間がかかる可能性があることを議論し、GitHubがノートブックをレンダリングできるようになったので便利です。ノートブックやgitを使用しないチームメンバーと共有するための差分と.htmlに使用される.pyファイルのエクスポート用に追加された自動保存フックがあります。

https://towardsdatascience.com/version-control-for-jupyter-notebook-3e6cef13392d

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.