version-control - 関数 - ジュピター ノート ブック mac




バージョン管理下でのIPythonノートブックの使用 (10)

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

ノートブックのフォーマットは、バージョン管理のために非常に適しています。ノートブックと出力をバージョン管理したい場合、これは非常にうまくいきます。 煩わしいのは、特に映画やプロットのための大きなバイナリ・ブロブである可能性のあるセル出力(別名「ビルド・プロダクト」)を除いて、入力をバージョン管理することだけを望む場合です。 特に、次のような優れたワークフローを見つけようとしています。

  • 私は出力を含めるか除外するかを選択することができますが、
  • 私がそれを望まないと私が誤って出力をコミットするのを防ぎ、
  • 私は自分のローカルバージョンで出力を保つことができますが、
  • 私は私のバージョンコントロールシステムを使って入力を変更したときを見ることができます(つまり、私は入力をコントロールしていますが、ローカルファイルに出力がある場合、入力が変更されたかどうかを確認できます)version control statusコマンドを使用すると、ローカルファイルに出力があるため、常に差分が登録されます。
  • 更新されたきれいなノートブックから作業用ノートブック(出力を含む)を更新することができます。 (更新)

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

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

私は以下で議論するいくつかのオプションを検討しましたが、まだ包括的な解決策を見つける必要はありません。 完全なソリューションは、IPythonにいくつかの変更が必要な場合があります。あるいは、単純な外部スクリプトに依存している場合もあります。 私は現在、 水銀を使用していますが、 gitでも動作するソリューションが欲しいです。理想的な解決策は、バージョン管理には無関係です。

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

アップデート: Gregory Crosswhiteの提案を使用して保存するたびに.cleanバージョンを保存することができます。 これは私の制約の大部分を満たしますが、以下の問題は解決されません。

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

ノート

出力の削除(ストリッピング)

  • ノートブックが実行されているときに、 Cell/All Output/Clearメニューオプションを使用して出力を削除することができます。
  • 出力を削除するスクリプトnbstripout.pyなど、出力を削除するスクリプトnbstripout.pyありますが、ノートブックインターフェイスを使用した場合と同じ出力は生成されません。 これは最終的にipython/nbconvertリポジトリに含まれていましたが、これは変更がipython/ipythonに含まれていますが、対応する機能はまだ組み込まれていないようです。 (update) Gregory Crosswhiteの解決策は、 ipython/nbconvertを呼び出さなくても、これを実行するのはかなり簡単であることを示しています。このアプローチは、 ipython/nbconvertできるならば、おそらく実行可能です。 、良いアイデアのようには思われません - これはどうにかして、ノ​​ートブックのメカニズムにフックする必要があります。)

ニュースグループ

問題

プルリクエスト


GitHubは今ノートブックをレンダリングすることができるので、それは生成に時間がかかるかもしれないとの議論とノートブックの出力を保持する必要がありますポストで議論されたアイデアはどうですか? ノートやgitを使用していないチームメンバーと共有するためにdiffや.htmlに使われる.pyファイルをエクスポートするために自動保存フックが追加されています。

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


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

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')

nbstripout.pyでの議論nbstripout.py 、コミット時にipynbファイルからの出力を自動的に削除するgitフィルタを作成するのが現在のベスト・ソリューションのようです。

ここで私はそれを働かせるために何をしましたか(その議論からコピーしました):

最新のIPythonをインポートできないときにcfriedlineのnbstripoutファイルを少し修正しました: https://github.com/petered/plato/blob/fb2f4e252f50c79768920d0e47b870a8d799e92b/notebooks/config/strip_notebook_output : https://github.com/petered/plato/blob/fb2f4e252f50c79768920d0e47b870a8d799e92b/notebooks/config/strip_notebook_outputそして私のレポに追加しました。 ./relative/path/to/strip_notebook_output言う

また、ファイル.gitattributesファイルをrepoのルートに追加しました。

*.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実行してsource setup_git_filters.sh 。 ファンキーな$(git rev-parse ...)は、(Unix)マシン上のあなたのレポのローカルパスを見つけることです。


otherに基づいてnbstripout.pyを作成しました。これはGitとMercurialの両方をサポートしています(mforbesのおかげで)。 これは、コマンドラインでスタンドアロンで使用するか、 nbstripout install / nbstripout uninstallnbstripout installして現在のリポジトリにnbstripout installフィルタとして使用することを目的としています。

PyPIから取得するか、単純に

pip install nbstripout

ここで私の解決策は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でのみ動作します
  • もしあなたが支店のsomebranch 、あなたがgit checkout otherbranch; git checkout somebranchブランチをしているのであれば、gitでgit checkout otherbranch; git checkout somebranch git checkout otherbranch; git checkout somebranchでは、通常、作業ツリーは変更されないと予想されます。 ここでは代わりに、2つのブランチ間でソースが異なるノートブックの出力とセル番号を失います。
  • より一般的には、Gregoryのソリューションと同様に、出力はまったくバージョン化されません。 チェックアウトに関係する作業を行うたびにそれを投げ捨てるのではなく、別のファイルに格納することでアプローチを変更することができます(ただし、上記のコードが実行された時点でコミットIDは不明です) (おそらく、 git commit notebook_file.ipynb以上のものが必要であることに気づくでしょうが、少なくともgit diff notebook_file.ipynbはbase64ガベージから解放されます)。
  • あなたが何らかの出力を含むコードを引っ張った場合(つまり、このアプローチを使用していない他の人がコミットした場合)、出力は正常にチェックアウトされます。 ローカルで生成された出力のみが失われます。

私のソリューションは、私が個人的に生成されたものをバージョン管理するのが好きではないという事実を反映しています。出力を含むマージを行うと出力生産性が無効になることがほぼ確実です。

編集:

  • 私が提案したようにソリューションを採用すれば(グローバルに)、いくつかのgitリポジトリを出力したい場合には問題があります。 したがって、特定のgitリポジトリの出力フィルタを無効にしたい場合は、その内部に.git / info / attributesファイルを作成するだけです

    **。ipynb filter =

内容として 明らかに、同じように、逆を行うことも可能です:特定のリポジトリに対してのみフィルタリングを有効にします。

  • コードは今では独自のgitリポジトリで管理されています

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

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

EDIT :2016年5月(2017年2月更新):スクリプトにはいくつかの選択肢があります。完全性のために、私が知っているリストはnbstripoutother variants )、 nbstripjqです。


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

ここを見てください

https://github.com/sat28/githubcommit


掘り起こした後、私は最終的にJupyterのドキュメント上でこの比較的単純な事前セーブフックを見つけました。 セル出力データを取り除きます。 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

Rich Signellの答えから :

あなたのjupyter_notebook_config.pyファイルを見つけるディレクトリが不明な場合は、 jupyter --config-dir [コマンドプロンプト/ターミナル]に入力することができます。そこにファイルが見つからない場合は、 jupyter notebook --generate-config入力してjupyter notebook --generate-config


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

背景として、Gitのaddコマンドは、ファイルに加えられた変更をステージング領域に保存します。 これをやってしまえば、ファイルへのその後の変更はGitで無視されます。 したがって、次のスクリプトは、指定されたファイルごとに、すべてのoutputsprompt_number sectionsprompt_number sections 、取り除かれたファイルをステージングし、元のファイルを復元します。

注:これを実行すると、 ImportError: No module named IPython.nbformatようなエラーメッセージが表示されます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ます。


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

ノートを再生成するには(repoをチェックアウトしたり、ブランチを切り替えた後に)、私は自分のノートブックを保存しているディレクトリに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フィルタを使ってノートブックから出力を取り除きます。 これを行う方法に関する議論がnbstripout.pyありnbstripout.py


私はこの問題を解決するPythonパッケージを構築しました

https://github.com/brookisme/gitnb

gitリポジトリ内のノートを追跡/更新/差分するためのgitに忠実な構文をCLIに提供します。

Heresの例

# 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 repoにコミットしていることに注意してください。 基本的には

# 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"

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





jupyter-notebook