ipynb importiert eine andere ipynb-Datei

90

Interaktives Python (ipython) ist einfach unglaublich, vor allem, wenn Sie Dinge im Handumdrehen zusammensetzen ... und dies so, dass es einfach ist, zurück zu gehen.

Interessant erscheint jedoch der Anwendungsfall mehrerer Ipython-Notebooks (Ipynb-Dateien). Es scheint, als ob ein Notebook KEINE Beziehung zu anderen Notebooks haben soll, was Sinn macht, außer dass ich gerne andere ipynb-Dateien importieren würde.

Die einzige Problemumgehung, die ich sehe, ist das Konvertieren meiner * .ipynb-Dateien in * .py-Dateien, die dann in mein Notizbuch importiert werden können. Es ist etwas seltsam, wenn eine Datei alles in einem Projekt enthält, besonders wenn ich wirklich auf die Wiederverwendung von Code drängen möchte (ist das nicht ein zentraler Grundsatz von Python?).

Vermisse ich etwas Ist dies nicht ein unterstützter Anwendungsfall für Ipython-Notebooks? Gibt es eine andere Lösung, die ich für diesen Import einer ipynb-Datei in ein anderes Notebook verwenden kann? Ich würde gerne weiterhin ipynb verwenden, aber es bringt meinen Workflow momentan wirklich durcheinander :(

Andrew Harris
quelle
Mögliches Duplikat: stackoverflow.com/questions/19082397/…
Warren Weckesser
2
Sie können den Notebook-Server mit starten --script, um .py-Kopien Ihrer Notebooks zu speichern. In IPython 2.0 können Sie %runein Notebook verwenden. Wir arbeiten immer noch an besseren Mechanismen für die Wiederverwendung von Code.
Thomas K
1
Dieses Beispiel zeigt, wie IPython-Notizbücher als Module importiert werden, ohne Duplikate als Skripte zu exportieren.
Minrk

Antworten:

130

In neueren Jupyter ist es wirklich einfach:

%run MyOtherNotebook.ipynb
Johndodo
quelle
5
% run MyOtherNotebook.ipynb hat den Job für mich erledigt. (nein '')
Florian H
6
Seien Sie vorsichtig, diese Methode führt das untergeordnete Notizbuch vollständig aus. Sie können eine Überprüfung hinzufügen, um __name__ == '__main__' and '__file__' not in globals()zu überprüfen, ob Sie sich im untergeordneten Notizbuch befinden. (von blog.sicara.com/… )
Flavian Hautbois
8
% run 'MyOtherNotebook.ipynb' FEHLER: root: Datei u'MyOtherNotebook.ipynb.py'nicht gefunden.
user3673
1
@ Kocur4d Danke für die Korrektur! Interessanterweise hat es bei mir (mit Anführungszeichen) funktioniert, als ich es ausprobiert habe, aber Beispiele in der Dokumentation haben keine Anführungszeichen.
Johndodo
3
Wenn jemand darauf stößt, können Sie auch den vollständigen Pfad wie% run "/path/to/my/file/notebook.ipynb"
Jeremie
33

Wenn Sie importieren möchten A.ipynbin B.ipynbSchreib

import import_ipynb
import A

in B.ipynb.

Das von import_ipynbmir erstellte Modul wird über pip installiert:

pip install import_ipynb

Es ist nur eine Datei und hält sich strikt an das offizielle Howto auf der Jupiter-Website.

PS Es unterstützt auch Dinge wie from A import foo, from A import *etc

Axil
quelle
@Crash pip install import-ipynbfunktioniert auch und installiert genau das gleiche Paket, aber da Sie mit Python nicht schreiben können import import-ipynbund es sich nur um eine Datei handelt, pip install import_ipynbsieht es für mich konsistenter aus.
Axil
3
Gibt es einen Unterschied zwischen import nbimporterund import import_ipynb?
Fractale
1
Dies funktioniert in meinem Jupyter mit Python 3
Sebastialonso
@Sebastialonso Was genau funktioniert nicht? Beschreiben Sie, was Sie tun und welche Fehlermeldungen angezeigt werden. Öffnen Sie idealerweise ein Ticket auf Github.
Axil
@axil Ich habe den gleichen Fehler, bei dem es bei mir in Py3 nicht funktioniert. Es gibt mir folgenden Fehler - ModuleNotFoundError: Kein Modul mit dem Namen 'A' PS: A.ipynb existiert im selben Ordner
Soman Dubey
10

Lauf

!pip install ipynb

und importieren Sie dann das andere Notebook als

from ipynb.fs.full.<notebook_name> import *

oder

from ipynb.fs.full.<notebook_name> import <function_name>

Stellen Sie sicher, dass sich alle Notebooks im selben Verzeichnis befinden.

Bearbeiten 1: Die offizielle Dokumentation finden Sie hier - https://ipynb.readthedocs.io/en/stable/

Wenn Sie nur Klassen- und Funktionsdefinitionen aus einem Notizbuch importieren möchten (und nicht die Anweisungen der obersten Ebene), können Sie ipynb.fs.defsstattdessen anstelle von verwenden ipynb.fs.full. Die vollständige Zuweisung von Variablen in Großbuchstaben wird ebenfalls ausgewertet.

Malgo
quelle
Was ist, wenn mein Dateiname Leerzeichen enthält?
Sameh
Es wird empfohlen, kein Leerzeichen in Ihrem Dateinamen zu behalten
Malgo
2
Beachten Sie, dass in beiden beschriebenen Fällen das importierte Notizbuch vollständig ausgeführt wird. Das ipynbPaket unterstützt auch nur die teilweise Ausführung von Definitionen. Es ist ein offizielles Paket von IPyhton, daher glaube ich, dass dies die akzeptierte Antwort sein sollte.
amka66
Kann dies Notebooks in einen Ordner importieren? Zum BeispielMyFolder/book.ipynb
Bones225,
Das sah gut aus, fällt aber um, wenn es zB% matplotlib inline trifft ....
jtlz2
7

Installieren Sie ipynb über Ihre Eingabeaufforderung

pip install import-ipynb

Importieren Sie in Ihre Notebook-Datei

import import_ipynb

Verwenden Sie jetzt den regulären Importbefehl, um Ihre Datei zu importieren

import MyOtherNotebook
außerhalb der Welt
quelle
Die einfachste und doch erklärendste Antwort. Vielen Dank!
Der arme Jude
3

Sie können import nbimporterdann verwendenimport notebookName

Fractale
quelle
+1, nbimporter funktioniert wie ein Zauber für mich, auch kann es mit conda installiert werden:conda install -c conda-forge importnb
Zuku
2

Die oben genannten Kommentare sind sehr nützlich, aber etwas schwierig zu implementieren. Die folgenden Schritte können Sie ausprobieren, ich habe es auch versucht und es hat funktioniert:

  1. Laden Sie diese Datei im PY-Dateiformat von Ihrem Notizbuch herunter (diese Option finden Sie auf der Registerkarte Datei).
  2. Kopieren Sie nun die heruntergeladene Datei in das Arbeitsverzeichnis von Jupyter Notebook
  3. Sie können es jetzt verwenden. Importieren Sie einfach die .PY-Datei in die ipynb-Datei
Yash Bansal
quelle
hmm ... Ich habe die Datei callee.ipync in die Datei callee.py konvertiert und dann die Datei callee.py unter demselben Ordner mit caller.ipync auf das Notizbuch hochgeladen, und die Datei in caller.ipync, die ich gerade geschrieben habe import callee, konnte einfach nicht Arbeit.
Elsa Lin
ps das IPython ist Version: 5.1.0.
Elsa Lin
1

Das Problem ist, dass ein Notizbuch keine einfache Python-Datei ist. Die Schritte zum Importieren der .ipynbDatei werden im Folgenden beschrieben: Importieren des Notizbuchs

Ich füge den Code ein. Wenn Sie ihn benötigen, können Sie ihn einfach kopieren und einfügen. Beachten Sie, dass ich am Ende die import primesAussage habe. Das musst du natürlich ändern. Der Name meiner Datei ist primes.ipynb. Ab diesem Zeitpunkt können Sie den Inhalt dieser Datei wie gewohnt verwenden.

Ich wünschte, es gäbe eine einfachere Methode, aber diese stammt direkt aus den Dokumenten.
Hinweis: Ich verwende Jupyter, nicht Ipython.

import io, os, sys, types
from IPython import get_ipython
from nbformat import current
from IPython.core.interactiveshell import InteractiveShell


def find_notebook(fullname, path=None):
    """find a notebook, given its fully qualified name and an optional path

    This turns "foo.bar" into "foo/bar.ipynb"
    and tries turning "Foo_Bar" into "Foo Bar" if Foo_Bar
    does not exist.
    """
    name = fullname.rsplit('.', 1)[-1]
    if not path:
        path = ['']
    for d in path:
        nb_path = os.path.join(d, name + ".ipynb")
        if os.path.isfile(nb_path):
            return nb_path
        # let import Notebook_Name find "Notebook Name.ipynb"
        nb_path = nb_path.replace("_", " ")
        if os.path.isfile(nb_path):
            return nb_path


class NotebookLoader(object):
    """Module Loader for Jupyter Notebooks"""
    def __init__(self, path=None):
        self.shell = InteractiveShell.instance()
        self.path = path

    def load_module(self, fullname):
        """import a notebook as a module"""
        path = find_notebook(fullname, self.path)

        print ("importing Jupyter notebook from %s" % path)

        # load the notebook object
        with io.open(path, 'r', encoding='utf-8') as f:
            nb = current.read(f, 'json')


        # create the module and add it to sys.modules
        # if name in sys.modules:
        #    return sys.modules[name]
        mod = types.ModuleType(fullname)
        mod.__file__ = path
        mod.__loader__ = self
        mod.__dict__['get_ipython'] = get_ipython
        sys.modules[fullname] = mod

        # extra work to ensure that magics that would affect the user_ns
        # actually affect the notebook module's ns
        save_user_ns = self.shell.user_ns
        self.shell.user_ns = mod.__dict__

        try:
        for cell in nb.worksheets[0].cells:
            if cell.cell_type == 'code' and cell.language == 'python':
                # transform the input to executable Python
                code = self.shell.input_transformer_manager.transform_cell(cell.input)
                # run the code in themodule
                exec(code, mod.__dict__)
        finally:
            self.shell.user_ns = save_user_ns
        return mod


class NotebookFinder(object):
    """Module finder that locates Jupyter Notebooks"""
    def __init__(self):
        self.loaders = {}

    def find_module(self, fullname, path=None):
        nb_path = find_notebook(fullname, path)
        if not nb_path:
            return

        key = path
        if path:
            # lists aren't hashable
            key = os.path.sep.join(path)

        if key not in self.loaders:
            self.loaders[key] = NotebookLoader(path)
        return self.loaders[key]

sys.meta_path.append(NotebookFinder())

import primes
keim13
quelle
1

Es ist überhaupt kein Problem, Jupyter mit vorhandenen oder neuen Python .py-Modulen zu verwenden. Starten Sie bei laufendem Jupyter einfach Spyder (oder einen Editor Ihrer Wahl), um Ihre Modulklassendefinitionen in einer .py-Datei zu erstellen / ändern, und importieren Sie die Module dann nach Bedarf in Jupyter.

Eine Sache, die dies wirklich nahtlos macht, ist die Verwendung der magischen Erweiterung zum automatischen Laden. Die Dokumentation zum automatischen Laden finden Sie hier:

http://ipython.readthedocs.io/en/stable/config/extensions/autoreload.html

Hier ist der Code zum automatischen Neuladen des Moduls, wenn es geändert wurde:

# autoreload sets up auto reloading of modified .py modules
import autoreload
%load_ext autoreload
%autoreload 2

Beachten Sie, dass ich den in einer vorherigen Antwort erwähnten Code versucht habe, das Laden von .ipynb-Dateien als Module zu simulieren, und ihn zum Laufen gebracht habe, aber er erstickt, wenn Sie Änderungen an der .ipynb-Datei vornehmen. Es sieht so aus, als müssten Sie die Jupyter-Entwicklungsumgebung neu starten, um das .ipynb-Modul neu zu laden, was für mich nicht akzeptabel war, da ich viele Änderungen an meinem Code vornehme.

David Miller
quelle
0

__init__.pyStellen Sie sicher, dass Sie dem Paket auch eine Datei hinzufügen , in der sich alle anderen .ipynb-Dateien befinden.

Dies ist zusätzlich zu der Verbindung , die nbviewer minrkund syioben vorgesehen ist .

Ich hatte auch ein ähnliches Problem und schrieb dann die Lösung sowie einen Link zu meinem öffentlichen Google Drive-Ordner, der ein funktionierendes Beispiel enthält :)

Mein Stackoverflow-Beitrag mit schrittweisen Experimenten und Lösungen:

Jupyter Notebook: Importieren Sie die IPynb-Datei und greifen Sie auf die Methode in einer anderen IPynb-Datei zu, die einen Fehler verursacht

Hoffe, das wird auch anderen helfen. Vielen Dank an alle!

Anugrah
quelle