Преобразование в (не из) формата ipython Notebook
IPython Notebook поставляется с nbconvert
, который может экспортировать ноутбуки в другие форматы. Но как преобразовать текст в противоположном направлении? Я спрашиваю, потому что у меня уже есть материалы и хороший рабочий процесс, в другом формате, но я бы хотел использовать интерактивную среду Notebook.
Вероятное решение: ноутбук можно создать, импортировав файл .py
, и в документации указано, что, когда nbconvert
экспортирует ноутбук в виде python script, он вводит директивы в комментарии, которые можно использовать для воссоздания записная книжка. Но информация поставляется с оговоркой об ограничениях этого метода, и принятый формат не документирован нигде, что я мог бы найти. (Образец показан, как ни странно, в разделе, посвященном записной книжке JSON format). Может ли кто-нибудь предоставить дополнительную информацию или лучшую альтернативу?
Изменить (1 марта 2016 года): Принятый ответ больше не работает, потому что по какой-то причине этот формат ввода не поддерживается версией 4 API-порта для ноутбуков. Я добавил самостоятельный ответ, в котором показано, как импортировать ноутбук с текущим (v4) API. (Я не принимаю текущий ответ, так как он решил мою проблему в то время и указал мне на ресурсы, которые я использовал в своем автоответчике.)
Ответы
Ответ 1
Следующее работает для IPython 3, но не для IPython 4.
API IPython имеет функции для чтения и записи файлов записной книжки. Вы должны использовать этот API, а не создавать JSON напрямую. Например, следующий фрагмент кода преобразует скрипт test.py
в блокнот test.ipynb
.
import IPython.nbformat.current as nbf
nb = nbf.read(open('test.py', 'r'), 'py')
nbf.write(nb, open('test.ipynb', 'w'), 'ipynb')
Что касается формата файла .py, понятного для nbf.read, то лучше просто заглянуть в класс синтаксического анализатора IPython.nbformat.v3.nbpy.PyReader. Код можно найти здесь (он не очень большой):
https://github.com/ipython/ipython/blob/master/jupyter_nbformat/v3/nbpy.py
Изменить: Этот ответ был изначально написан для IPyhton 3. Я не знаю, как сделать это правильно с IPython 4. Вот обновленная версия ссылки выше, указывающая на версию nbpy.py
из IPython 3.2.1 релиз:
https://github.com/ipython/ipython/blob/rel-3.2.1/IPython/nbformat/v3/nbpy.py
В основном вы используете специальные комментарии, такие как # <codecell>
или # <markdowncell>
, чтобы отделить отдельные ячейки. Посмотрите на операторы line.startswith
в PyReader.to_notebook
для полного списка.
Ответ 2
Так как код в принятом ответе больше не работает, я добавил этот автоответ, который показывает, как импортировать в ноутбук с текущим (v4
) API.
Формат ввода
Версии 2 и 3 API-интерфейса IPython Notebook могут импортировать питон script со специальными комментариями структурирования и разбить его на ячейки по желанию. Здесь образец входного файла (оригинальная документация здесь). Первые две строки игнорируются и необязательны. (На самом деле, читатель будет игнорировать строки coding:
и <nbformat>
в любом месте файла.)
# -*- coding: utf-8 -*-
# <nbformat>3.0</nbformat>
# <markdowncell>
# The simplest notebook. Markdown cells are embedded in comments,
# so the file is a valid `python` script.
# Be sure to **leave a space** after the comment character!
# <codecell>
print("Hello, IPython")
# <rawcell>
# Raw cell contents are not formatted as markdown
(API также принимает устаревшие директивы <htmlcell>
и <headingcell level=...>
, которые немедленно преобразуются в другие типы.)
Как импортировать его
По какой-то причине этот формат не поддерживается версией 4 API-интерфейса Notebook. Это по-прежнему хороший формат, поэтому стоит поддержать его, импортировав его в версию 3 и обновив ее. В принципе это всего две строки кода, плюс i/o:
from IPython.nbformat import v3, v4
with open("input-file.py") as fpin:
text = fpin.read()
nbook = v3.reads_py(text)
nbook = v4.upgrade(nbook) # Upgrade v3 to v4
jsonform = v4.writes(nbook) + "\n"
with open("output-file.ipynb", "w") as fpout:
fpout.write(jsonform)
Но не так быстро! Фактически, API-интерфейс ноутбука имеет неприятную ошибку: если последняя ячейка на входе является ячейкой уценки, v3.reads_py()
потеряет ее. Простейший подход - это наклеить на фиктивную ячейку <markdown>
в конце: ошибка удалит ее, и все будут счастливы. Поэтому перед передачей text
в v3.reads_py()
выполните следующие действия:
text += """
# <markdowncell>
# If you can read this, reads_py() is no longer broken!
"""
Ответ 3
очень старый вопрос, я знаю. но есть jupytext
(также доступен на pypi), который можно конвертировать из ipynb
в несколько форматов и обратно.
когда установлен jupytext
, вы можете использовать
$ jupytext --to notebook test.py
для генерации test.ipynb
.
jupytext
имеет гораздо больше интересных функций, которые могут пригодиться при работе с ноутбуками.
вот более свежий вопрос на эту тему.
Ответ 4
Пример кода Python, как построить IP-блокнот V4:
# -*- coding: utf-8 -*-
import os
from base64 import encodestring
from IPython.nbformat.v4.nbbase import (
new_code_cell, new_markdown_cell, new_notebook,
new_output, new_raw_cell
)
# some random base64-encoded *text*
png = encodestring(os.urandom(5)).decode('ascii')
jpeg = encodestring(os.urandom(6)).decode('ascii')
cells = []
cells.append(new_markdown_cell(
source='Some NumPy Examples',
))
cells.append(new_code_cell(
source='import numpy',
execution_count=1,
))
cells.append(new_markdown_cell(
source='A random array',
))
cells.append(new_raw_cell(
source='A random array',
))
cells.append(new_markdown_cell(
source=u'## My Heading',
))
cells.append(new_code_cell(
source='a = numpy.random.rand(100)',
execution_count=2,
))
cells.append(new_code_cell(
source='a = 10\nb = 5\n',
execution_count=3,
))
cells.append(new_code_cell(
source='a = 10\nb = 5',
execution_count=4,
))
cells.append(new_code_cell(
source=u'print "ünîcødé"',
execution_count=3,
outputs=[new_output(
output_type=u'execute_result',
data={
'text/plain': u'<array a>',
'text/html': u'The HTML rep',
'text/latex': u'$a$',
'image/png': png,
'image/jpeg': jpeg,
'image/svg+xml': u'<svg>',
'application/json': {
'key': 'value'
},
'application/javascript': u'var i=0;'
},
execution_count=3
),new_output(
output_type=u'display_data',
data={
'text/plain': u'<array a>',
'text/html': u'The HTML rep',
'text/latex': u'$a$',
'image/png': png,
'image/jpeg': jpeg,
'image/svg+xml': u'<svg>',
'application/json': {
'key': 'value'
},
'application/javascript': u'var i=0;'
},
),new_output(
output_type=u'error',
ename=u'NameError',
evalue=u'NameError was here',
traceback=[u'frame 0', u'frame 1', u'frame 2']
),new_output(
output_type=u'stream',
text='foo\rbar\r\n'
),new_output(
output_type=u'stream',
name='stderr',
text='\rfoo\rbar\n'
)]
))
nb0 = new_notebook(cells=cells,
metadata={
'language': 'python',
}
)
import IPython.nbformat as nbf
import codecs
f = codecs.open('test.ipynb', encoding='utf-8', mode='w')
nbf.write(nb0, f, 4)
f.close()
Ответ 5
В соответствии с примером, сделанным Володимиром Копеем, я собрал bare-bones script для преобразования .py, полученного путем экспорта из .ipynb обратно в V4.ipynb.
Я взломал этот script вместе, когда я отредактировал (в правильной среде IDE).py, который я экспортировал из ноутбука, и я хотел вернуться к Notebook, чтобы запустить его по ячейке.
script обрабатывает только ячейки кода. Во всяком случае экспортированный .py не содержит ничего другого.
import nbformat
from nbformat.v4 import new_code_cell,new_notebook
import codecs
sourceFile = "changeMe.py" # <<<< change
destFile = "changeMe.ipynb" # <<<< change
def parsePy(fn):
""" Generator that parses a .py file exported from a IPython notebook and
extracts code cells (whatever is between occurrences of "In[*]:").
Returns a string containing one or more lines
"""
with open(fn,"r") as f:
lines = []
for l in f:
l1 = l.strip()
if l1.startswith('# In[') and l1.endswith(']:') and lines:
yield "".join(lines)
lines = []
continue
lines.append(l)
if lines:
yield "".join(lines)
# Create the code cells by parsing the file in input
cells = []
for c in parsePy(sourceFile):
cells.append(new_code_cell(source=c))
# This creates a V4 Notebook with the code cells extracted above
nb0 = new_notebook(cells=cells,
metadata={'language': 'python',})
with codecs.open(destFile, encoding='utf-8', mode='w') as f:
nbformat.write(nb0, f, 4)
Никаких гарантий, но это сработало для меня
Ответ 6
Получил свободу принимать и модифицировать код P.Toccateli и alexis, чтобы он также работал с pycharm и spyder как клеточные маркеры и выпустил его на github.
Ответ 7
Я написал расширение для vscode, которое может помочь. Он преобразует файлы Python в записные книжки ipython. Это на ранних стадиях, поэтому, если возникнет какая-либо ошибка, не стесняйтесь представить вопрос.
Jupyter Notebook Converter
Ответ 8
Надеюсь, я не опоздал.
Я только что опубликовал пакет Python для PyPI под названием p2j. Этот пакет создает блокнот Jupyter .ipynb
из исходного кода Python .py
.
pip install p2j
p2j script.py
Пример записной книжки Jupyter, созданной из файла .py
:
![Example of .ipynb generated from a .py file]()
PyPI: https://pypi.org/project/p2j/
GitHub: https://github.com/remykarem/python2jupyter
Ответ 9
Вы можете использовать скрипт py2nb с https://github.com/sklam/py2nb
Вам нужно будет использовать определенный синтаксис для вашего *.py, но он довольно прост в использовании (посмотрите на пример в папке 'samples')