ipynb zaimportuj inny plik ipynb

90

Interaktywny Python (ipython) jest po prostu niesamowity, zwłaszcza, że ​​układasz rzeczy w locie ... i robisz to w taki sposób, że łatwo jest wrócić.

Jednak to, co wydaje się interesujące, to przypadek użycia posiadania wielu notatników ipython (pliki ipynb). Wygląda na to, że notatnik NIE powinien mieć związku z innymi notatnikami, co ma sens, z wyjątkiem tego, że chciałbym zaimportować inne pliki ipynb.

Jedyne obejście, jakie widzę, to przekonwertowanie moich plików * .ipynb na pliki * .py, które następnie można zaimportować do mojego notatnika. Posiadanie jednego pliku zawierającego wszystko w projekcie jest trochę dziwne, zwłaszcza jeśli naprawdę chcę naciskać na ponowne użycie kodu (czy nie jest to podstawowa zasada Pythona?).

Czy coś mi brakuje? Czy to nie jest obsługiwany przypadek użycia notebooków ipython? Czy istnieje inne rozwiązanie, którego mogę użyć do tego importu pliku ipynb do innego notebooka? Chciałbym nadal używać ipynb, ale teraz naprawdę psuje mi to przepływ pracy :(

Andrew Harris
źródło
Możliwy duplikat: stackoverflow.com/questions/19082397/…
Warren Weckesser
2
Możesz uruchomić serwer notebooków za pomocą, --scriptaby zapisać kopie .py swoich notatników. W IPython 2.0 możesz mieć %runnotebooka. Wciąż pracujemy nad lepszymi mechanizmami ponownego wykorzystania kodu.
Thomas K,
1
Ten przykład pokazuje, jak zaimportować notatniki IPython jako moduły bez eksportowania duplikatów jako skryptów.
minrk

Odpowiedzi:

130

W nowszym Jupyter jest to naprawdę proste:

%run MyOtherNotebook.ipynb
johndodo
źródło
5
% run MyOtherNotebook.ipynb wykonał pracę za mnie. (nie '')
Florian H
6
Uważaj, ta metoda całkowicie uruchomi notatnik podrzędny. Możesz dodać czek, __name__ == '__main__' and '__file__' not in globals()aby sprawdzić, czy jesteś w notesie podrzędnym. (z blog.sicara.com/… )
Flavian
8
% run 'MyOtherNotebook.ipynb' BŁĄD: root: u'MyOtherNotebook.ipynb.py'Nie znaleziono pliku .
user3673
1
@ Kocur4d Dzięki za naprawienie! Co ciekawe, działało to dla mnie (z cudzysłowami), kiedy go wypróbowałem, ale przykłady w dokumentacji nie mają żadnych cytatów.
johndodo
3
jeśli ktoś się na to natknie, możesz również użyć pełnej ścieżki, takiej jak% run "/path/to/my/file/notebook.ipynb"
Jeremie
33

Jeśli chcesz importować A.ipynbw B.ipynbzapisie

import import_ipynb
import A

w B.ipynb.

Utworzony import_ipynbprzeze mnie moduł jest instalowany przez pip:

pip install import_ipynb

To tylko jeden plik i jest ściśle zgodny z oficjalnym howto na stronie jupyter.

PS Obsługuje również takie rzeczy from A import foo, from A import *etc

pachwina
źródło
@Crash pip install import-ipynbrównież działa i instaluje ten sam pakiet, ale ponieważ Python nie pozwala ci pisać import import-ipynbi biorąc pod uwagę, że jest to tylko jeden plik, pip install import_ipynbwygląda dla mnie bardziej spójnie.
axil
3
Czy jest jakaś różnica między import nbimporteri import import_ipynb?
Fractale
1
To w ogóle nie działa w moim Jupyterze z Pythonem 3
Sebastialonso
@Sebastialonso Co dokładnie nie działa? Opisz, co robisz i jakie komunikaty o błędach widzisz. Najlepiej otwórz bilet na githubie.
kąt
@axil Mam ten sam błąd, gdzie nie działa dla mnie w Py3. Daje mi następujący błąd - ModuleNotFoundError: Żaden moduł o nazwie 'A' PS: A.ipynb nie istnieje w tym samym folderze
Soman Dubey
10

Biegać

!pip install ipynb

a następnie zaimportuj drugi notatnik jako plik

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

lub

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

Upewnij się, że wszystkie notatniki znajdują się w tym samym katalogu.

Edycja 1: Możesz zobaczyć oficjalną dokumentację tutaj - https://ipynb.readthedocs.io/en/stable/

Ponadto, jeśli chcesz zaimportować tylko definicje klas i funkcji z notatnika (a nie instrukcje najwyższego poziomu), możesz użyć ipynb.fs.defszamiast ipynb.fs.full. Ocenione zostanie również przypisanie do zmiennych pełnych wielkich liter.

Malgo
źródło
Co się stanie, jeśli moja nazwa pliku zawiera spacje?
Sameh
Zaleca się, aby w nazwie pliku nie było żadnych spacji
Malgo
2
Należy pamiętać, że w obu opisanych przypadkach importowany notatnik jest wykonywany w całości. ipynbPakiet obsługuje również częściowe wykonanie tylko definicji. Jest to oficjalny pakiet firmy IPyhton, więc uważam, że powinna to być akceptowana odpowiedź.
amka66
Czy to może zaimportować notatniki do folderu? na przykładMyFolder/book.ipynb
bones225
Wyglądało to dobrze, ale przewraca się, gdy napotyka np.% Matplotlib inline ....
jtlz2
7

Zainstaluj ipynb z wiersza poleceń

pip install import-ipynb

Zaimportuj do pliku notatnika

import import_ipynb

Teraz użyj zwykłego polecenia importu, aby zaimportować plik

import MyOtherNotebook
poza światem
źródło
Najprostsza, ale wyjaśniająca odpowiedź. Dzięki!
Biedny Żyd
3

Możesz import nbimporterwtedy użyćimport notebookName

Fractale
źródło
+1, nbimporter działa dla mnie jak urok, również można go zainstalować za pomocą conda:conda install -c conda-forge importnb
Zuku
2

Powyższe komentarze są bardzo przydatne, ale są nieco trudne do wdrożenia. Poniżej kroki możesz spróbować, ja też próbowałem i zadziałało:

  1. Pobierz ten plik z notatnika w formacie pliku PY (tę opcję znajdziesz na karcie Plik).
  2. Teraz skopiuj pobrany plik do katalogu roboczego notatnika Jupyter
  3. Jesteś teraz gotowy do użycia. Po prostu zaimportuj plik .PY do pliku ipynb
Yash Bansal
źródło
hmm ... Przekonwertowałem plik callee.ipync na callee.py, a następnie załadowałem plik callee.py do notebooka w tym samym folderze z caller.ipync i in caller.ipync, który właśnie napisałem import callee, po prostu nie mogłem praca.
Elsa Lin
ps wersja IPythona: 5.1.0.
Elsa Lin
1

Problem polega na tym, że notatniki nie są zwykłym plikiem Pythona. Kroki, aby zaimportować .ipynbplik, przedstawiono poniżej: Importowanie notatnika

Wklejam kod, więc jeśli potrzebujesz ... możesz po prostu szybko skopiować i wkleić. Zauważ, że na końcu mam import primesoświadczenie. Oczywiście będziesz musiał to zmienić. Nazwa mojego pliku to primes.ipynb. Od tego momentu możesz używać zawartości tego pliku tak, jak robisz to regularnie.

Żałuję, że nie było prostszej metody, ale jest to prosto z dokumentacji.
Uwaga: używam jupyter, a nie 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
germ13
źródło
1

Nie ma żadnego problemu z używaniem Jupyter z istniejącymi lub nowymi modułami Python .py. Po uruchomieniu Jupyter po prostu uruchom Spyder (lub dowolny wybrany przez siebie edytor), aby zbudować / zmodyfikować definicje klas modułów w pliku .py, a następnie po prostu zaimportuj moduły w razie potrzeby do Jupyter.

Jedną rzeczą, która sprawia, że ​​jest to naprawdę płynne, jest użycie rozszerzenia magicznego automatycznego przeładowania. Dokumentację dotyczącą automatycznego ładowania można znaleźć tutaj:

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

Oto kod, który automatycznie przeładowuje moduł po każdej modyfikacji:

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

Zauważ, że wypróbowałem kod wspomniany we wcześniejszej odpowiedzi, aby symulować ładowanie plików .ipynb jako modułów i uruchomiłem go, ale dławi się, gdy wprowadzasz zmiany w pliku .ipynb. Wygląda na to, że musisz ponownie uruchomić środowisko programistyczne Jupyter, aby ponownie załadować „moduł” .ipynb, co było dla mnie nie do przyjęcia, ponieważ wprowadzam wiele zmian w moim kodzie.

David Miller
źródło
0

Upewnij się, że __init__.pyw pakiecie dodano również plik, w którym znajdują się wszystkie inne pliki .ipynb.

Jest to dodatek do łącza nbviewer że minrki syipodany powyżej.

Miałem też podobny problem i wtedy napisałem rozwiązanie oraz link do mojego publicznego folderu na dysku Google, na którym działa przykład :)

Mój post Stackoverflow z eksperymentami krok po kroku i rozwiązaniem:

Notatnik Jupyter: Importuj plik .ipynb i uzyskaj dostęp do jego metody w innym pliku .ipynb, powodując błąd

Mam nadzieję, że pomoże to również innym. Dziękuje wszystkim!

anugrah
źródło