如何通过命令行将 Python Notebook 转换为 Python 文件?
Posted
技术标签:
【中文标题】如何通过命令行将 Python Notebook 转换为 Python 文件?【英文标题】:How do I convert a IPython Notebook into a Python file via commandline? 【发布时间】:2013-06-09 06:33:47 【问题描述】:我正在考虑使用 *.ipynb 文件作为事实来源,并以编程方式将它们“编译”成 .py 文件以用于计划的作业/任务。
我理解的唯一方法是通过 GUI。有没有办法通过命令行做到这一点?
【问题讨论】:
“真相的来源”是什么意思? IPython 笔记本只是 json 文件。您可以加载它们并作为 Python 字典进行操作。对于源代码,您应该迭代input
键,其中cell_type
等于“代码”。看看这个scheme
嗯,我想将 .ipynb 存储在存储库中,而不是 .py 文件。因此,作为“构建步骤”,我会将 .ipynb 转换为 .py 文件以供自动化系统实际使用。你是对的,我可以只加载 json 并只输出代码单元,但我想知道是否已经有什么东西可以为我做到这一点:)
@StefanKrawczyk 您能否将回答标记为已接受?我会推荐 wwwilliam 的 asnwer
【参考方案1】:
如果不想每次保存都输出一个 Python 脚本,或者不想重启 IPython 内核:
在命令行,您可以使用nbconvert
:
$ jupyter nbconvert --to script [YOUR_NOTEBOOK].ipynb
作为一个小技巧,您甚至可以通过预先添加 !
(用于任何命令行参数)来调用上述命令 in IPython notebook .在笔记本内:
!jupyter nbconvert --to script config_template.ipynb
在--to script
是added 之前,选项是--to python
或--to=python
,但在向与语言无关的笔记本系统的转变中是renamed。
【讨论】:
如果您确实想要每次保存一次,在jupyter
中,您可以通过保存前或保存后挂钩触发nbconvert
:ContentsManager.pre_save_hook
abd FileContentsManager.post_save_hook
。您将添加一个保存后挂钩jupyter nbconvert --to script [notebook]
有没有办法做相反的事情,即从 python 脚本转换为笔记本。对于前 - 有一些专门的文档字符串被解析成单元格?
转换文件夹jupyter nbconvert --to script /path/to/notebooks/*.ipynb
中的所有笔记本
谢谢,它可以工作!但是如果我不想在脚本中使用# In[ ]:
类型的东西,我希望它是干净的。有什么办法吗?
@RishabhAgrahari 以下似乎对我有用。 !jupyter nbconvert --to script --no-prompt notebook.ipynb
【参考方案2】:
如果要将当前目录下的所有*.ipynb
文件转换为python脚本,可以这样运行命令:
jupyter nbconvert --to script *.ipynb
【讨论】:
或者你可以运行:ipython nbconvert --to script *.ipynb 要像在函数中那样以编程方式进行转换,请使用以下语法:subprocess.run(['jupyter', 'nbconvert',ipynb_file,"--to", "script","--output", r'temp_converted_py'],shell=True) 注意 ipynb_file 是一个变量【参考方案3】:这是一种不使用 ipython 从 V3 或 V4 ipynb 提取代码的快速而肮脏的方法。它不检查细胞类型等。
import sys,json
f = open(sys.argv[1], 'r') #input.ipynb
j = json.load(f)
of = open(sys.argv[2], 'w') #output.py
if j["nbformat"] >=4:
for i,cell in enumerate(j["cells"]):
of.write("#cell "+str(i)+"\n")
for line in cell["source"]:
of.write(line)
of.write('\n\n')
else:
for i,cell in enumerate(j["worksheets"][0]["cells"]):
of.write("#cell "+str(i)+"\n")
for line in cell["input"]:
of.write(line)
of.write('\n\n')
of.close()
【讨论】:
如果您不想安装任何 Jupyter 工具的最佳答案。 我喜欢这个。但是当我从 Jupyter 笔记本下载 .py 格式时发现,即使我在 Windows 上,它也使用 UNIX 行结尾。要生成相同的内容,请将newlines='\n'
添加为打开输出文件调用中的第三个参数。 (Python 3.x)
这个答案打开了读取标签并仅提取那些具有它的单元格的可能性。单独通过命令行更难做到。【参考方案4】:
遵循上一个示例,但使用 新的 nbformat 库版本:
import nbformat
from nbconvert import PythonExporter
def convertNotebook(notebookPath, modulePath):
with open(notebookPath) as fh:
nb = nbformat.reads(fh.read(), nbformat.NO_CONVERT)
exporter = PythonExporter()
source, meta = exporter.from_notebook_node(nb)
with open(modulePath, 'w+') as fh:
fh.writelines(source.encode('utf-8'))
【讨论】:
的最后一行代码 fh.writelines(source.encode('utf-8')) 给出 'TypeError: write() argument must be str, not int' fh.writelines(source ) 虽然有效。 遇到了同样的问题,通过将.encode('utf-8')
放在最后一行来解决。
我解决了最后一行的问题写fh.write(source)
而不是fh.writelines(...)
。【参考方案5】:
Jupytext 很高兴在您的工具链中进行此类转换。它不仅允许从笔记本转换为脚本,还可以从脚本再次返回到笔记本。甚至还制作了执行形式的笔记本。
jupytext --to py notebook.ipynb # convert notebook.ipynb to a .py file
jupytext --to notebook notebook.py # convert notebook.py to an .ipynb file with no outputs
jupytext --to notebook --execute notebook.py # convert notebook.py to an .ipynb file and run it
【讨论】:
显然还有ipynb-py-convert,见here。 'jupytext' 不是内部或外部命令、可运行程序或批处理文件。??? 你安装了吗@AmineChadi。请参阅here 了解如何执行此操作。如果您通过笔记本使用它作为命令行界面,您可以在笔记本中运行%pip install jupytext
。【参考方案6】:
您可以通过 IPython API 执行此操作。
from IPython.nbformat import current as nbformat
from IPython.nbconvert import PythonExporter
filepath = 'path/to/my_notebook.ipynb'
export_path = 'path/to/my_notebook.py'
with open(filepath) as fh:
nb = nbformat.reads_json(fh.read())
exporter = PythonExporter()
# source is a tuple of python source code
# meta contains metadata
source, meta = exporter.from_notebook_node(nb)
with open(export_path, 'w+') as fh:
fh.writelines(source)
【讨论】:
【参考方案7】:我知道这是一个旧线程。我遇到了同样的问题,想通过命令行将 .pynb 文件转换为 .py 文件。
我的搜索将我带到ipynb-py-convert
通过以下步骤,我能够获得 .py 文件
-
安装“pip install ipynb-py-convert”
通过命令提示符进入保存ipynb文件的目录
输入命令
> ipynb-py-convert YourFileName.ipynb YourFilename.py
例如:。 ipynb-py-convert 开始使用-kaggle-titanic-problem.ipynb 开始使用-kaggle-titanic-problem.py
上面的命令将创建一个名为“YourFileName.py”的python脚本,根据我们的示例,它将创建getting-started-with-kaggle-titanic-problem.py
文件
【讨论】:
【参考方案8】:用于将当前目录下的所有*.ipynb格式文件递归转换为python脚本:
for i in *.ipynb **/*.ipynb; do
echo "$i"
jupyter nbconvert "$i" "$i"
done
【讨论】:
我必须添加--to script
参数以避免 Jupiter 4.4.0 中的默认 html 输出。【参考方案9】:
以下示例将名为 a_notebook.ipynb
的 Iron Python Notebook 转换为名为 a_python_script.py
的 Python 脚本,省略了用关键字 remove
标记的单元格,我将其手动添加到我不想结束的单元格中在脚本中,省略了可视化和其他步骤,一旦我完成了笔记本,我就不需要由脚本执行。
import nbformat as nbf
from nbconvert.exporters import PythonExporter
from nbconvert.preprocessors import TagRemovePreprocessor
with open("a_notebook.ipynb", 'r', encoding='utf-8') as f:
the_notebook_nodes = nbf.read(f, as_version = 4)
trp = TagRemovePreprocessor()
trp.remove_cell_tags = ("remove",)
pexp = PythonExporter()
pexp.register_preprocessor(trp, enabled= True)
the_python_script, meta = pexp.from_notebook_node(the_notebook_nodes)
with open("a_python_script.py", 'w', encoding='utf-8') as f:
f.writelines(the_python_script)
【讨论】:
【参考方案10】:有一个非常棒的包,名为nb_dev,专为在 Jupyter Notebooks 中编写 Python 包而设计。与nbconvert,
一样,它可以将笔记本转换为 .py 文件,但它更加灵活和强大,因为它具有许多不错的附加创作功能,可帮助您在 PyPI 上开发测试、文档和注册包。它是由 fast.ai 开发的。
它有一点学习曲线,但文档很好,总体上不难。
【讨论】:
【参考方案11】:我遇到了这个问题,并试图在网上找到解决方案。虽然我找到了一些解决方案,但它们仍然存在一些问题,例如,当您从仪表板启动新笔记本时,烦人的 Untitled.txt
自动创建。
所以最终我写了my own solution:
import io
import os
import re
from nbconvert.exporters.script import ScriptExporter
from notebook.utils import to_api_path
def script_post_save(model, os_path, contents_manager, **kwargs):
"""Save a copy of notebook to the corresponding language source script.
For example, when you save a `foo.ipynb` file, a corresponding `foo.py`
python script will also be saved in the same directory.
However, existing config files I found online (including the one written in
the official documentation), will also create an `Untitile.txt` file when
you create a new notebook, even if you have not pressed the "save" button.
This is annoying because we usually will rename the notebook with a more
meaningful name later, and now we have to rename the generated script file,
too!
Therefore we make a change here to filter out the newly created notebooks
by checking their names. For a notebook which has not been given a name,
i.e., its name is `Untitled.*`, the corresponding source script will not be
saved. Note that the behavior also applies even if you manually save an
"Untitled" notebook. The rationale is that we usually do not want to save
scripts with the useless "Untitled" names.
"""
# only process for notebooks
if model["type"] != "notebook":
return
script_exporter = ScriptExporter(parent=contents_manager)
base, __ = os.path.splitext(os_path)
# do nothing if the notebook name ends with `Untitled[0-9]*`
regex = re.compile(r"Untitled[0-9]*$")
if regex.search(base):
return
script, resources = script_exporter.from_filename(os_path)
script_fname = base + resources.get('output_extension', '.txt')
log = contents_manager.log
log.info("Saving script at /%s",
to_api_path(script_fname, contents_manager.root_dir))
with io.open(script_fname, "w", encoding="utf-8") as f:
f.write(script)
c.FileContentsManager.post_save_hook = script_post_save
要使用这个脚本,你可以把它添加到~/.jupyter/jupyter_notebook_config.py
:)
请注意,您可能需要重新启动 jupyter notebook/lab 才能使其工作。
【讨论】:
链接失效【参考方案12】:在我的薄荷 [ubuntu] 系统上,即使已经安装了 jupyter 并且笔记本也可以工作,jupyter nbconvert --to script
给出了错误 no file/directory,直到我做了一个单独的
sudo apt-get install jupyter-nbconvert
然后,转换一切正常。我只是想添加这个以防有人遇到同样的错误(对我来说这很令人困惑,因为我认为没有文件错误指的是笔记本,它肯定在本地目录中,我花了一段时间才意识到子命令不是已安装)。
【讨论】:
【参考方案13】:使用 nbconvert 6.07 和 jupyter 客户端 6.1.12:
将 jupyter notebook 转换为 python 脚本
$ jupyter nbconvert mynotebook.ipynb --to python
将 jupyter notebook 转换为指定输出文件名的 python 脚本
$ jupyter nbconvert mynotebook.ipnb --to python --output myscript.py
【讨论】:
【参考方案14】:%notebook foo.ipynb
魔术命令会将当前的 IPython 导出到“foo.ipynb”。
更多信息请输入%notebook?
【讨论】:
以上是关于如何通过命令行将 Python Notebook 转换为 Python 文件?的主要内容,如果未能解决你的问题,请参考以下文章
如何通过命令行将 XML 文件导入“Charles Proxy > Map Local”