wake-up-neo.com

Verwenden von IPython-Notizbüchern unter Versionskontrolle

Was ist eine gute Strategie, um IPython Notebooks unter Versionskontrolle zu halten?

Das Notebook-Format ist sehr gut für die Versionskontrolle geeignet: Wenn man das Notebook und die Ausgaben versionieren möchte, funktioniert dies recht gut. Der Ärger kommt, wenn man nur die Eingabe versionieren möchte, ausgenommen die Zellenausgaben (alias "Build-Produkte"), bei denen es sich um große binäre Blobs handeln kann, insbesondere für Filme und Plots. Insbesondere versuche ich, einen guten Workflow zu finden, der:

  • ermöglicht mir die Auswahl zwischen Ein- und Ausschließen der Ausgabe.
  • verhindert, dass ich versehentlich eine Ausgabe mache, wenn ich es nicht will,
  • erlaubt mir die Ausgabe in meiner lokalen Version zu behalten,
  • ermöglicht es mir, mithilfe meines Versionskontrollsystems zu sehen, wann ich Änderungen an den Eingaben vorgenommen habe (dh wenn ich nur die Eingaben versioniere, meine lokale Datei jedoch Ausgaben enthält, möchte ich in der Lage sein, zu sehen, ob sich die Eingaben geändert haben (was ein Festschreiben erfordert) Bei Verwendung des Befehls version control status wird immer ein Unterschied registriert, da die lokale Datei Ausgaben enthält.)
  • ermöglicht mir das Aktualisieren meines Arbeitsnotizbuchs (das die Ausgabe enthält) von einem aktualisierten, sauberen Notizbuch. (Update)

Wie bereits erwähnt, ist alles in Ordnung, wenn ich die Ausgaben einbeziehe (was zum Beispiel bei Verwendung von nbviewer wünschenswert ist). Das Problem ist, wenn ich nicht die Ausgabe versionieren will. Es gibt einige Tools und Skripte zum Entfernen der Ausgabe des Notizbuchs, aber häufig treten die folgenden Probleme auf:

  1. Ich habe versehentlich eine Version mit der Ausgabe festgeschrieben, wodurch mein Repository verschmutzt wurde.
  2. Ich lösche die Ausgabe, um die Versionskontrolle zu verwenden, möchte aber die Ausgabe lieber in meiner lokalen Kopie behalten (manchmal dauert es zum Beispiel eine Weile, bis sie wieder hergestellt ist).
  3. Einige der Skripte, die die Ausgabe entfernen, ändern das Format geringfügig im Vergleich zur Menüoption Cell/All Output/Clear, Wodurch unerwünschtes Rauschen in den Diffs erzeugt wird. Dies wird durch einige der Antworten gelöst.
  4. Wenn ich Änderungen an einer sauberen Version der Datei abrufen möchte, muss ich eine Möglichkeit finden, diese Änderungen in mein Arbeitsnotizbuch zu integrieren, ohne alles erneut ausführen zu müssen. (Update)

Ich habe mehrere Optionen in Betracht gezogen, die ich im Folgenden erörtern werde, aber noch keine gute umfassende Lösung gefunden. Für eine vollständige Lösung sind möglicherweise einige Änderungen an IPython erforderlich oder es werden einfache externe Skripts benötigt. Ich verwende derzeit Mercurial , möchte aber eine Lösung, die auch mit git funktioniert: Eine ideale Lösung wäre versionierungsunabhängig.

Dieses Problem wurde schon oft diskutiert, aber es gibt aus Benutzersicht keine endgültige oder eindeutige Lösung. Die Antwort auf diese Frage sollte die endgültige Strategie liefern. Es ist in Ordnung, wenn eine neuere (auch in Entwicklung befindliche) Version von IPython oder eine einfach zu installierende Erweiterung erforderlich ist.

Update: Ich habe mit meinem modifizierten Notizbuch Version gespielt, die optional bei jedem Speichern eine .clean - Version speichert mit Gregory Crosswhite Vorschläge . Dies erfüllt die meisten meiner Einschränkungen, lässt jedoch Folgendes ungelöst:

  1. Dies ist noch keine Standardlösung (erfordert eine Änderung der ipython-Quelle. Gibt es eine Möglichkeit, dieses Verhalten mit einer einfachen Erweiterung zu erreichen? Benötigt eine Art On-Save-Hook.
  2. Ein Problem, das ich mit dem aktuellen Workflow habe, ist das Abrufen von Änderungen. Diese kommen in die .clean - Datei und müssen dann irgendwie in meine Arbeitsversion integriert werden. (Natürlich kann ich das Notizbuch jederzeit erneut ausführen, aber dies kann sehr schmerzhaft sein, insbesondere wenn einige der Ergebnisse von langen Berechnungen, parallelen Berechnungen usw. abhängen.) Ich habe noch keine gute Idee, wie dies behoben werden kann . Vielleicht könnte ein Workflow mit einer Erweiterung wie ipycache funktionieren, aber das scheint ein bisschen zu kompliziert zu sein.

Anmerkungen

Entfernen (Abisolieren) der Ausgabe

  • Wenn das Notebook läuft, können Sie die Ausgabe über die Menüoption Cell/All Output/Clear Entfernen.
  • Es gibt einige Skripte zum Entfernen der Ausgabe, z. B. das Skript nbstripout.py , das die Ausgabe entfernt, jedoch nicht die gleiche Ausgabe wie über die Notebook-Benutzeroberfläche erzeugt. Dies wurde schließlich in das Repo ipython/nbconvert aufgenommen, aber dieses wurde geschlossen und besagt, dass die Änderungen jetzt in ipython/ipython enthalten sind, aber die entsprechende Funktionalität scheint dies nicht zu haben wurde noch aufgenommen. (update) Allerdings Gregory Crosswhite's Lösung zeigt, dass dies ziemlich einfach ist, auch ohne aufzurufen ipython/nbconvert , daher ist dieser Ansatz wahrscheinlich praktikabel, wenn er ordnungsgemäß eingebunden werden kann. (Das Anhängen an jedes Versionskontrollsystem scheint jedoch keine gute Idee zu sein - dies sollte sich irgendwie in den Notebook-Mechanismus einbinden .)

Newsgroups

Probleme

Pull-Anfragen

537
mforbes

Hier ist meine Lösung mit Git. Sie können wie gewohnt einfach hinzufügen und festschreiben (und unterscheiden): Diese Vorgänge ändern nicht Ihren Arbeitsbaum, und gleichzeitig ändert das (erneute) Ausführen eines Notizbuchs nicht Ihren Git-Verlauf.

Obwohl dies wahrscheinlich an andere VCS angepasst werden kann, weiß ich, dass es nicht Ihren Anforderungen entspricht (zumindest die VSC-Agnostizität). Trotzdem ist es perfekt für mich und obwohl es nichts besonders Geniales ist und viele Leute es wahrscheinlich bereits benutzen, habe ich keine klaren Anweisungen gefunden, wie man es durch googeln umsetzt. So kann es für andere Menschen nützlich sein.

  1. Speichern Sie eine Datei mit dieser Inhalt irgendwo (für das Folgende nehmen wir an ~/bin/ipynb_output_filter.py)
  2. Mach es ausführbar (chmod +x ~/bin/ipynb_output_filter.py)
  3. Erstellen Sie die Datei ~/.gitattributes Mit folgendem Inhalt

    *.ipynb    filter=dropoutput_ipynb
    
  4. Führen Sie die folgenden Befehle aus:

    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
    

Getan!

Einschränkungen:

  • es funktioniert nur mit git
  • wenn Sie sich in git in der Verzweigung somebranch befinden und git checkout otherbranch; git checkout somebranch ausführen, erwarten Sie normalerweise, dass der Arbeitsbaum unverändert bleibt. Hier haben Sie stattdessen die Ausgabe und die Zellennummerierung von Notizbüchern verloren, deren Quelle sich zwischen den beiden Zweigen unterscheidet.
  • im Allgemeinen ist die Ausgabe überhaupt nicht versioniert, wie bei Gregorys Lösung. Um es nicht jedes Mal wegzuwerfen, wenn Sie etwas mit einem Checkout zu tun haben, können Sie die Vorgehensweise ändern, indem Sie es in separaten Dateien speichern (beachten Sie jedoch, dass zum Zeitpunkt der Ausführung des obigen Codes die Commit-ID nicht bekannt ist!). und möglicherweise Versionierung (aber beachten Sie, dass dies etwas mehr als ein git commit notebook_file.ipynb erfordern würde, obwohl es mindestens git diff notebook_file.ipynb frei von Base64-Müll halten würde).
  • übrigens: Wenn Sie Code abrufen (d. h. von einer anderen Person, die diesen Ansatz nicht verwendet), der eine Ausgabe enthält, wird die Ausgabe normal ausgecheckt. Nur die lokal produzierte Ausgabe geht verloren.

Meine Lösung spiegelt die Tatsache wider, dass ich generierte Inhalte persönlich nicht gerne versioniert halte. Beachten Sie, dass das Durchführen von Zusammenführungen mit der Ausgabe fast garantiert die Ausgabe ungültig macht. oder Ihre Produktivität oder beides.

EDIT:

  • wenn Sie die von mir vorgeschlagene Lösung übernehmen - also global -, haben Sie Probleme, falls Sie für einige Git-Repos eine Versionsausgabe wünschen . Wenn Sie die Ausgabefilterung für ein bestimmtes Git-Repository deaktivieren möchten, erstellen Sie einfach eine Datei . Git/info/attributes mit

    **. ipynb filter =

als Inhalt. Auf die gleiche Weise ist es natürlich auch möglich, das Gegenteil zu tun: Aktivieren Sie die Filterung only für ein bestimmtes Repository.

  • der Code wird nun in einem eigenen gepflegt Git Repo

  • wenn die obigen Anweisungen zu ImportErrors führen, fügen Sie "ipython" vor dem Pfad des Skripts hinzu:

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

[~ # ~] edit [~ # ~] : Mai 2016 (aktualisiert Februar 2017): Es gibt verschiedene Alternativen zu meinem Skript - der Vollständigkeit halber hier ist eine Liste von denen, die ich kenne: nbstripout ( othervariant ), nbstrip , jq .

115

Wir haben ein Gemeinschaftsprojekt, in dem das Produkt Jupyter Notebooks ist, und wir haben in den letzten sechs Monaten einen Ansatz gewählt, der hervorragend funktioniert: Wir aktivieren das automatische Speichern der .py - Dateien und verfolgen beide .ipynb - Dateien und die Dateien .py.

Wenn jemand das neueste Notizbuch ansehen/herunterladen möchte, kann er dies über Github oder Nbviewer tun. Wenn jemand sehen möchte, wie sich der Notizbuchcode geändert hat, kann er sich die Änderungen am .py Ansehen. Dateien.

Bei Jupyter Notebook-Servern kann dies durch Hinzufügen der Zeilen erreicht werden

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

in die Datei jupyter_notebook_config.py und starten Sie den Notebook-Server neu.

Wenn Sie nicht sicher sind, in welchem ​​Verzeichnis Sie Ihre jupyter_notebook_config.py - Datei finden, können Sie jupyter --config-dir Eingeben. Wenn Sie die Datei dort nicht finden, können Sie sie durch Eingabe von jupyter notebook --generate-config.

Bei Ipython 3 - Notebook-Servern kann dies durch Hinzufügen der Zeilen erreicht werden

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

in die Datei ipython_notebook_config.py und starten Sie den Notebook-Server neu. Diese Zeilen stammen aus einer Github-Antwort @ minrk zur Verfügung gestellt und @dror schließt sie auch in seine SO Antwort ein.

Bei Ipython 2 - Notebook-Servern kann dies erreicht werden, indem der Server gestartet wird mit:

ipython notebook --script

oder durch Hinzufügen der Zeile

c.FileNotebookManager.save_script = True

in die Datei ipython_notebook_config.py und starten Sie den Notebook-Server neu.

Wenn Sie nicht sicher sind, in welchem ​​Verzeichnis Sie Ihre ipython_notebook_config.py - Datei finden, können Sie ipython locate profile default Eingeben. Wenn Sie die Datei dort nicht finden, können Sie sie durch Eingabe von ipython profile create.

Hier ist nser Projekt über Github, das diesen Ansatz verwendet : und hier ist Github-Beispiel für die Erkundung der letzten Änderungen an einem Notizbuch .

Wir waren sehr zufrieden damit.

58
Rich Signell

Ich habe nbstripout erstellt, basierend auf MinRKs Gist , das sowohl Git als auch Mercurial unterstützt (dank mforbes). Es soll entweder eigenständig in der Befehlszeile oder als Filter verwendet werden, der über nbstripout install/nbstripout uninstall Einfach im aktuellen Repository (un) installiert werden kann.

Holen Sie es sich von PyPI oder einfach

pip install nbstripout
36
kynan

Hier ist eine neue Lösung von Cyrille Rossant für IPython 3.0, die weiterhin Dateien abzeichnet und keine json-basierten ipymd-Dateien:

https://github.com/rossant/ipymd

13
Spencer Boucher

(2017-02)

Strategien

  • on_commit ():
    • strip die Ausgabe> name.ipynb (nbstripout,)
    • strip die Ausgabe> name.clean.ipynb (nbstripout,)
    • immer nbconvert zu python: name.ipynb.py (nbconvert)
    • immer in markdown konvertieren: name.ipynb.md (nbconvert, ipymd)
  • vcs.configure ():
    • git difftool, mergetool: nbdiff und nbmerge von nbdime

Werkzeuge

11
Wes Turner

Endlich habe ich einen produktiven und einfachen Weg gefunden, um Jupyter und Git zusammen zu bringen. Ich bin noch in den ersten Schritten, aber ich denke schon, dass es so ist viel besser als alle anderen gewundenen Lösungen.

Visual Studio Code ist ein cooler und offener Quellcode-Editor von Microsoft. Es hat eine exzellente Python Erweiterung, mit der Sie jetzt ein Jupyter Notebook importieren als python Code.

Nachdem Sie Ihr Notizbuch in eine python -Datei importiert haben, befinden sich der gesamte Code und die Markierung in einer normalen python -Datei mit speziellen Markierungen in Kommentaren. Sie können im Bild unten sehen:

VSCode editor with a notebook converted to python

Ihre python -Datei enthält nur den Inhalt der Notebook-Eingabezellen. Die Ausgabe wird in einem geteilten Fenster generiert. Sie haben reinen Code im Notizbuch, er ändert sich nicht, während Sie ihn nur ausführen. Keine gemischte Ausgabe mit Ihrem Code. Kein seltsames, unverständliches Json-Format zur Analyse Ihrer Diffs.

Nur reiner python Code, mit dem Sie jeden einzelnen Diff leicht identifizieren können.

Ich muss meine .ipynb - Dateien nicht mehr versionieren. Ich kann eine *.ipynb - Zeile in .gitignore Einfügen.

Müssen Sie ein Notizbuch erstellen, um es zu veröffentlichen oder mit jemandem zu teilen? Kein Problem, einfach klicken Sie auf die Exportschaltfläche im interaktiven Fenster python

Exporting a python file to Notebook format

Ich benutze es nur für einen Tag, aber endlich kann ich Jupyter glücklich mit Git verwenden.

P .: VSCode-Code-Vervollständigung ist viel besser als Jupyter.

9
neves

Wie von hervorgehoben, ist --script In 3.x Veraltet. Dieser Ansatz kann durch Anwenden eines Post-Save-Hooks verwendet werden. Fügen Sie insbesondere Folgendes zu ipython_notebook_config.py Hinzu:

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

Der Code stammt aus # 8009 .

8
Dror

Nach einigen Jahren des Entfernens von Ausgaben in Notebooks habe ich versucht, eine bessere Lösung zu finden. Ich verwende jetzt Jupytext , eine Erweiterung für Jupyter Notebook und Jupyter Lab, die ich entworfen habe.

Jupytext kann Jupyter-Notizbücher in verschiedene Textformate (Scripts, Markdown und R Markdown) konvertieren. Und umgekehrt. Es bietet auch die Möglichkeit, pair ein Notizbuch in eines dieser Formate zu kopieren und die beiden Darstellungen des Notizbuchs automatisch zu synchronisieren (ein .ipynb und ein .md/.py/.R Datei).

Lassen Sie mich erklären, wie Jupytext die obigen Fragen beantwortet:

ermöglicht mir die Auswahl zwischen Ein- und Ausschließen der Ausgabe.

Das .md/.py/.R Datei enthält nur die Eingabezellen. Sie sollten diese Datei immer verfolgen. Version der .ipynb Datei nur, wenn Sie die Ausgaben verfolgen möchten.

verhindert, dass ich versehentlich eine Ausgabe mache, wenn ich es nicht will,

Hinzufügen *.ipynb bis .gitignore

erlaubt mir die Ausgabe in meiner lokalen Version zu behalten,

Die Ausgaben werden im (lokalen) .ipynb Datei

ermöglicht es mir, mithilfe meines Versionskontrollsystems zu sehen, wann ich Änderungen an den Eingaben vorgenommen habe (dh wenn ich nur die Eingaben versioniere, meine lokale Datei jedoch Ausgaben enthält, möchte ich in der Lage sein, zu sehen, ob sich die Eingaben geändert haben (was ein Festschreiben erfordert) Bei Verwendung des Befehls version control status wird immer ein Unterschied registriert, da die lokale Datei Ausgaben enthält.)

Der Unterschied auf dem .py/.R oder .md Datei ist was Sie suchen

ermöglicht mir das Aktualisieren meines Arbeitsnotizbuchs (das die Ausgabe enthält) von einem aktualisierten, sauberen Notizbuch. (aktualisieren)

Ziehen Sie die neueste Version des .py/.R oder .md Datei und aktualisieren Sie Ihr Notizbuch in Jupyter (Strg + R). Sie erhalten die neuesten Eingabezellen aus der Textdatei, mit passenden Ausgaben aus dem .ipynb Datei. Der Kernel ist nicht betroffen, was bedeutet, dass Ihre lokalen Variablen erhalten bleiben - Sie können an der Stelle weiterarbeiten, an der Sie sie verlassen haben.

Was ich an Jupytext liebe, ist, dass das Notizbuch (in Form eines .py/.R oder .md Datei) kann in Ihrer bevorzugten IDE bearbeitet werden. Mit diesem Ansatz wird das Refactoring eines Notebooks zum Kinderspiel. Sobald Sie fertig sind, müssen Sie nur noch das Notizbuch in Jupyter aktualisieren.

Wenn du es versuchen willst: installiere Jupytext mit pip install jupytext und starte deinen Jupyter Notebook oder Lab Editor neu. Öffnen Sie das Notizbuch, für das Sie die Versionskontrolle durchführen möchten, und Pairing verknüpfen Sie es mit einer Markdown-Datei (oder einem Skript) über Jupytext-Menü in Jupyter-Notizbuch (oder - Jupytext-Befehle in Jupyter Lab). Speichern Sie Ihr Notizbuch, und Sie erhalten die beiden Dateien: das Original .ipynb, sowie die versprochene Textdarstellung des Notebooks, die perfekt zur Versionskontrolle passt!

Für diejenigen, die interessiert sein könnten: Jupytext ist auch in der Befehlszeile verfügbar.

8
Marc Wouts

Stoßen Sie einfach auf "jupytext", das wie eine perfekte Lösung aussieht. Es generiert eine .py-Datei aus dem Notizbuch und hält dann beide synchron. Sie können Eingaben über die .py-Datei versionieren, vergleichen und zusammenführen, ohne die Ausgaben zu verlieren. Wenn Sie das Notizbuch öffnen, werden die Eingabezellen mit der Erweiterung ".py" und die Ausgabe mit der Erweiterung ".ipynb" erstellt. Und wenn Sie die Ausgabe in git aufnehmen möchten, können Sie einfach das ipynb hinzufügen.

https://github.com/mwouts/jupytext

7
simon

Die oben genannten, sehr beliebten Antworten für 2016 sind inkonsistente Hacks, verglichen mit dem besseren Weg, dies 2019 zu tun.

Es gibt mehrere Optionen. Die beste Antwort auf diese Frage ist Jupytext.

Jupytext

Lesen Sie den Towards Data Science-Artikel zu Jupytext

Bei der Versionskontrolle werden sowohl die PY- als auch die IPYNB-Dateien in die Versionskontrolle übernommen. Sehen Sie sich die .py-Datei an, wenn Sie den Eingabeunterschied möchten, und die .ipynb-Datei, wenn Sie die zuletzt gerenderte Ausgabe möchten.

Bemerkenswerte Erwähnungen: VS Studio, nbconvert, nbdime, Wasserstoff

Ich denke, mit ein bisschen mehr Arbeit werden VS Studio und/oder Wasserstoff (oder ähnliches) die dominierenden Akteure bei der Lösung dieses Workflows sein.

7
SwimBikeRun

Leider weiß ich nicht viel über Mercurial, aber ich kann Ihnen eine mögliche Lösung anbieten, die mit Git funktioniert, in der Hoffnung, dass Sie meine Git-Befehle in ihre Mercurial-Entsprechungen übersetzen können.

Für den Hintergrund speichert der Befehl add in Git die Änderungen, die an einer Datei vorgenommen wurden, in einem Staging-Bereich. Sobald Sie dies getan haben, werden alle nachfolgenden Änderungen an der Datei von Git ignoriert, es sei denn, Sie weisen sie an, diese ebenfalls bereitzustellen. Daher das folgende Skript, das für jede der angegebenen Dateien alle outputs und Prompt_number sections, stuft die entfernte Datei ein und stellt dann das Original wieder her:

HINWEIS: Wenn dies ausgeführt wird, erhalten Sie eine Fehlermeldung wie ImportError: No module named IPython.nbformat, und verwenden Sie dann ipython, um das Skript anstelle von python auszuführen.

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)

Nachdem das Skript für die Dateien ausgeführt wurde, deren Änderungen Sie festschreiben möchten, führen Sie einfach git commit.

7

Ich benutze einen sehr pragmatischen Ansatz; die für mehrere Notebooks an mehreren Seiten gut funktionieren. Und es ermöglicht mir sogar, Notizbücher zu übertragen. Es funktioniert sowohl für Windows als auch für Unix/MacOS.
Al dachte, es ist einfach, ist die oben genannten Probleme zu lösen ...

Konzept

Grundsätzlich tun nicht verfolgen Sie die .ipnyb- Dateien, nur die entsprechenden .py- Dateien.
Durch Starten des Notebook-Servers mit dem --script Option, diese Datei wird automatisch erstellt/gespeichert, wenn das Notebook gespeichert wird.

Jene .py- Dateien enthalten alle Eingaben; Nicht-Code wird in Kommentaren gespeichert, ebenso wie die Zellränder. Diese Dateien können gelesen/importiert (und in den Notebook-Server gezogen) werden, um ein Notebook (neu) zu erstellen. Nur die Ausgabe ist weg; bis es erneut ausgeführt wird.

Persönlich benutze ich Mercurial , um den .py files; und benutze die normalen (Kommandozeilen-) Befehle, um das hinzuzufügen, checke ein (ect). Die meisten anderen (D) VCS erlauben dies.

Es ist einfach, die Geschichte jetzt zu verfolgen; das .py sind klein, textuell und einfach zu unterscheiden. Hin und wieder brauchen wir einen Klon (nur einen Zweig; dort einen zweiten Notebook-Server starten) oder eine ältere Version (auschecken und in einen Notebook-Server importieren) usw.

Tipps

  • Fügen Sie *. Ipynb zu '. Hgignore' hinzu, damit Mercurial weiß, dass diese Dateien ignoriert werden können
  • Erstellen Sie ein (Bash-) Skript, um den Server zu starten (mit dem --script Option) und verfolge die Version
  • Das Speichern eines Notizbuchs speichert das .py- Datei, aber checkt sie nicht ein .
    • Dies ist ein Nachteil: Das kann man vergessen
    • Es ist eine Funktion auch: Es ist möglich, ein Notizbuch zu speichern (und später fortzufahren), ohne den Repository-Verlauf zu gruppieren.

Wünscht sich

  • Es wäre schön, wenn Sie im Notebook-Dashboard Schaltflächen zum Einchecken/Hinzufügen/usw. hätten
  • Eine Kasse zu (am Beispiel) [email protected]+rev.py) sollte hilfreich sein Es wäre zu viel Arbeit, das hinzuzufügen; und vielleicht mache ich das mal. Bis jetzt mache ich das einfach per Hand.
6
Albert

Ich habe ein python - Paket erstellt, das dieses Problem löst

https://github.com/brookisme/gitnb

Es bietet eine CLI mit einer git-inspirierten Syntax zum Verfolgen/Aktualisieren/Vergleichen von Notebooks in Ihrem Git-Repo.

Hier ist ein Beispiel

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

Beachten Sie, dass der letzte Schritt, bei dem ich "gitnb commit" verwende, das Festschreiben Ihres Git-Repos ist. Es ist im Wesentlichen ein Wrapper für

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

Es gibt mehrere weitere Methoden, die so konfiguriert werden können, dass in jeder Phase mehr oder weniger Benutzereingaben erforderlich sind. Dies ist jedoch die allgemeine Idee.

3
brook

Da es so viele Strategien und Tools für die Versionskontrolle von Notebooks gibt, habe ich versucht, ein Flussdiagramm zu erstellen, um eine geeignete Strategie auszuwählen (erstellt im April 2019).

Decision flow to pick version control strategy

3
nik

Wenn Sie einen Unicode-Parsing-Fehler wie diesen erhalten, lesen Sie das ausgezeichnete Skript von Pietro Battiston nach:

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)

Sie können am Anfang des Skripts Folgendes hinzufügen:

reload(sys)
sys.setdefaultencoding('utf8')
3
Guillaume Dumas

Nachdem ich mich umgegraben hatte, fand ich endlich diesen relativ einfachen Pre-Save-Haken in den Jupyter-Dokumenten . Es werden die Zellenausgabedaten entfernt. Sie müssen es in die Datei jupyter_notebook_config.py Einfügen (Anweisungen siehe unten).

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

Von Rich Signells Antwort :

Wenn Sie nicht sicher sind, in welchem ​​Verzeichnis Sie Ihre jupyter_notebook_config.py - Datei finden sollen, können Sie jupyter --config-dir [In den Befehl Eingabeaufforderung/Terminal] eingeben. Wenn Sie die Datei dort nicht finden, können Sie dies erstellen Sie es, indem Sie jupyter notebook --generate-config eingeben.

3
binaryfunt

Ich habe das getan, was Albert & Rich getan hat - keine .ipynb-Dateien (da diese Bilder enthalten können, die chaotisch werden). Führen Sie stattdessen entweder immer ipython notebook --script Aus oder geben Sie c.FileNotebookManager.save_script = True In Ihre Konfigurationsdatei ein, damit beim Speichern Ihres Notizbuchs immer eine (versionierbare) .py - Datei erstellt wird.

Um Notizbücher neu zu generieren (nachdem ich ein Repo ausgecheckt oder einen Zweig gewechselt habe), habe ich das Skript py_file_to_notebooks.py in das Verzeichnis gestellt, in dem ich meine Notizbücher gespeichert habe.

Führen Sie nach dem Auschecken eines Repos einfach python py_file_to_notebooks.py Aus, um die ipynb-Dateien zu generieren. Nach dem Wechseln des Zweigs müssen Sie möglicherweise python py_file_to_notebooks.py -ov Ausführen, um die vorhandenen ipynb-Dateien zu überschreiben.

Um auf der sicheren Seite zu sein, sollten Sie auch *.ipynb Zu Ihrer .gitignore - Datei hinzufügen.

Bearbeiten: Ich mache das nicht mehr, weil (A) Sie Ihre Notizbücher jedes Mal aus PY-Dateien neu generieren müssen, wenn Sie einen Zweig auschecken, und (B) es andere Dinge wie Abschriften in Notizbüchern gibt, die Sie verlieren. Stattdessen entferne ich die Ausgabe von Notebooks mithilfe eines Git-Filters. Die Diskussion darüber ist hier .

2
Peter

Ok, es sieht also so aus, als ob die derzeit beste Lösung laut einer Diskussion hier darin besteht, einen Git-Filter zu erstellen, der die Ausgabe von ipynb-Dateien beim Festschreiben automatisch entfernt .

Hier ist, was ich getan habe, um es zum Laufen zu bringen (kopiert aus dieser Diskussion):

Ich habe die nbstripout-Datei von cfriedline leicht geändert, um einen informativen Fehler zu erhalten, wenn Sie das neueste IPython nicht importieren können: strip_notebook_output Und es zu meinem Repo hinzugefügt, sagen wir in ./relative/path/to/strip_notebook_output

Fügte außerdem die Datei .gitattributes zum Stammverzeichnis des Repository hinzu, die Folgendes enthält:

*.ipynb filter=stripoutput

Und erstellt ein setup_git_filters.sh enthält

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

Und rannte source setup_git_filters.sh. Die originelle $ (git rev-parse ...) Sache ist, den lokalen Pfad Ihres Repos auf jedem (Unix-) Rechner zu finden.

2
Peter

Mit dieser Jupyter-Erweiterung können Benutzer Jupyter-Notebooks direkt an Github senden.

Bitte schauen Sie hier

https://github.com/sat28/githubcommit

1
sat

Wie wäre es mit der Idee, die im folgenden Beitrag besprochen wird, wo die Ausgabe des Notizbuchs aufbewahrt werden soll, mit dem Argument, dass es möglicherweise lange dauern kann, sie zu erstellen, und es ist praktisch, da GitHub jetzt Notizbücher rendern kann. Es wurden Hooks zum automatischen Speichern für den Export von .py-Dateien hinzugefügt, die für Diffs und .html verwendet werden, um sie für Teammitglieder freizugeben, die keine Notebooks oder Git verwenden.

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