Python中文社区与papermill(ID:python-china)你是否曾经创建过Jupyternotebook并希望使用不同的参数集来生成notebook?为此,您可能至少完成了以下一项操作:?编辑单元格中的变量并重新运行笔记本,必要时保存一份副本。?保存笔记本的副本,并可能修改代码以直接在.ipynb文件中编辑值并重新运行笔记本?构建一些自定义代码以使用从数据库或配置文件加载的数据设置变量,然后重新运行笔记本这个问题有一个很好的解决方案,它允许交互式笔记本参数化并与自动化作业很好地共存,它被称为papermill。动机许多笔记本电脑用户使用将笔记本电脑顶部附近的单元格指定为全局变量的标准做法。然后修改单元格中的值并运行整个笔记本以获得不同的结果。为了保留输出,作者将手动下载另一种格式的笔记本或将其另存为不同的笔记本文件。但是仅使用笔记本服务器和这些手动方法很快就会变得混乱且难以遵循,更不用说容易出错了。你在编辑哪个笔记本?Papermill有助于解决这个问题。在这篇文章中,我将介绍papermill和基本用法,通过一个参数化示例,最后谈谈使用cron来完全安排和自动化笔记本执行。对于papermill,笔记本中的一个特殊单元格被指定为参数。当papermill通过命令行界面(CLI)或使用PythonAPI执行参数化笔记本时,参数将传入并在后续单元格中执行。这允许笔记本以不同的参数快速运行多次。然后可以将生成的执行笔记本保存在各种位置,包括本地或云存储。安装要安装papermill,请使用pip。我建议在虚拟环境中使用virtualenv或conda。我经常推荐使用pyenv安装最新的Python版本并创建一个virtualenv虚拟环境。如果您想使用各种输入和输出选项(如亚马逊的s3或微软的azure),pipinstallpapermill会安装所有依赖项。我不会在这里详细介绍,但文档涵盖了这些选项,您甚至可以扩展papermill以将额外的处理程序添加到笔记本的输入/输出(I/O)。pipinstallpapermill[all]基本用法大多数用户想用papermill做的第一件事是参数化笔记本。运行Jupyter并打开笔记本后,您需要做的就是将参数标签添加到包含参数的单元格中。保存笔记本,现在您可以使用papermill执行它。例如笔记本,使用CLI运行笔记本并提供您自己的名称。papermill-pnameMattpapermill_example1.ipynbpapermill_matt.ipynb此命令告诉papermill执行输入笔记本papermill_example1.ipynb并将输出写入papermill_matt.ipynb,同时将参数名称设置为值Matt。如果您打开生成的笔记本,它将在带有注入参数标签的参数标记之后包含一个新单元格,如下所示。您现在应该看到如何根据需要添加尽可能多的参数以从现有笔记本制作新笔记本。将主笔记本(在我们的例子中为papermill_example1.ipynb)想象成一个模板,您可以使用它通过快速注入参数来制作任意数量的副本。API的基本用法您可能希望使用Python代码来获取或构建您注入的参数,因此PythonAPI也可用于执行papermill。我们可以在Python脚本中实现与上面完全相同的结果(或者在笔记本中,它在那里也工作得很好——并且会动态地向您显示进度)。importpapermillaspmname="Matt"res=pm.execute_notebook('papermill_example1.ipynb','papermill_{name}.ipynb',parameters=dict(namename=name)){"version_major":2,"version_minor":0,"model_id":"cf8280b216094bf6a75a9536b6505051"}更多参数传递到目前为止,我们只传递了一个参数,并使用了-p选项来实现这一点。您可以通过多种方式传递参数。命令行您可以使用示例笔记本运行所有这些并亲自查看结果。首先,您可以从CLI指定几个参数。即使笔记本中尚不存在参数,也可以传入和创建参数。在这种情况下,papermill将创建一个注入参数单元格并在笔记本顶部执行它。这是一个例子。papermill-pnameMatt-plevel5-pfactor0.33-paliveTruepapermill_example1.ipynbpapermill_matt.ipynb或替换为长选项...papermill--parametersnameMatt--parameterslevel5--parametersfactor0.33--parametersaliveTruepapermill_example1.ipynbpapermill_matt.ipynb注意,或--parameters选项将尝试解析整数和浮点数,因此如果您希望将它们解释为字符串,请使用-r或--raw选项将所有值获取为字符串。papermill-rnameMatt-rlevel5-rfactor0.33-raliveTruepapermill_example1.ipynbpapermill_matt.ipynb也可以使用yaml指定参数。这可以作为文件(-f或--parameters_file)、字符串(-y或--parameters_yaml)或base64编码字符串(-b或--parameters_base64)传入。这允许您传入更复杂的数据,包括列表和字典。papermillpapermill_example1.ipynbpapermill_matt.ipynb-y"name:Mattlevel:5factor:0.33alive:Truesizes:-1.0-2.5-3.7params:x:3y:4"您可以轻松地对字符串进行base64编码。(在与Mac、Linux或WindowsWSL上的笔记本文件相同的目录中的shell中运行此命令)。echo"name:Mattlevel:5factor:0.33alive:Truesizes:-1.0-2.5-3.7params:x:3y:4">params.yaml现在可以运行文件版本了。papermillpapermill_example1.ipynbpapermill_matt.ipynb-fparams.yaml或base64版本PARAMS=$(catparams.yaml|base64)#makesthebase64versionoftheyamlfilepapermillpapermill_example1.ipynbpapermill_matt.ipynb-b$PARAMS无论哪种方式,你应该明白复杂的数据可以从命令行转换和API通过到笔记本。这些示例都使用本地文件系统进行笔记本输入和输出,但也可以从Amazons3、Azure、谷歌云存储或Web服务器读取和写入笔记本。检查笔记本您可以从CLI检查笔记本的可用参数。$papermill--help-notebookpapermill_example1.ipynbUsage:papermill[OPTIONS]NOTEBOOK_PATH[OUTPUT_PATH]Parametersinferredfornotebook'papermill_example1.ipynb':name:Unknowntype(default"Joe")或使用PythonAPI。pm.inspect_notebook('papermill_example1.ipynb'){'name':{'name':'name','inferred_type_name':'None','default':'"Joe"','help':''}}papermill的典型工作流程是拥有一个参数化的笔记本,使用多个值运行它,然后将生成的笔记本转换为另一种格式以供查看或报告。让我们通过一个示例来了解如何设置它。首先,我们有一个使用Yahoo!FinanceAPI获取股票价格并绘制股票的历史最高点(或至少过去两年,因为此时我只获取那么多数据)。如果你想运行这个例子,你需要确保你已经安装了yfinanceAPI和matplotlib。如果需要,您可以使用pip安装两者。我们可以使用papermillCLI检查参数。$papermill--help-notebookpapermill_example2.ipynbUsage:papermill[OPTIONS]NOTEBOOK_PATH[OUTPUT_PATH]Parametersinferredfornotebook'papermill_example2.ipynb':symbol:Unknowntype(default'AAPL')我们将使用几个符号运行这个笔记本。为此,我选择使用shell脚本,以便可以通过计划的cron程序运行它。如果需要,这可以使用简单的Python脚本轻松完成。但是,如果您使用的是虚拟环境,您可能最终需要一个脚本来确保正确加载virtualenv。在这种情况下,对整个过程使用shell脚本可能会更容易。我还将使用jupyternbconvert(或者您可以将其作为jupyter-nbconvert运行)命令将笔记本转换为html文件,以便通过Web浏览器查看。与papermill一样,nbconvert可通过命令行或使用PythonAPI使用。自动化脚本#!/bin/bashset-eux#activateourvirtualenv(thiswascreatedusingpyenv-virtualenv,yourswillbeelsewhere)source/Users/mcw/.pyenv/versions/3.8.6/envs/pandas/bin/activate#gettothescriptdirectoryifrunningviacroncd$(dirname"${BASH_SOURCE[0]}")forSinAAPLMSFTGOOGFBdopapermill-psymbol$Spapermill_example2.ipynbpapermill_${S}.ipynbjupyter-nbconvert--no-input--tohtmlpapermill_${S}.ipynbdone您可以从shell运行此命令(在调整激活的行之后之后的虚拟环境)。您还可以轻松地安排它在cron中定期运行。例如,您可以像这样(使用您自己的路径)在每个工作日的下午4点运行此报告。0016**mon-fri/Users/mcw/projects/python_blogposts/tools/run_papermill.shExtendedexample只要多一点创意(和nbconvert上的软件配置),您就可以通过电子邮件将笔记本导出为PDF或其他格式,或将它们上传到服务器以每天更新报告。请注意,每个符号的笔记本都保存到本地磁盘。它们可以在Jupyter服务器中打开,并在需要调试或进一步工作时轻松重新执行。请注意,如果您正在运行自动化作业,则每次运行时都会更换笔记本。理想情况下,在主模板笔记本上工作,然后通过自动化为每个符号生成新版本。另一个技巧是papermill可以读写标准输入和输出。这意味着如果您有其他将笔记本文件作为输入的工具,则不必将文件写入磁盘。例如,在上面的shell脚本中,我们可以避免为每个符号写出每个单独的笔记本文件,而是在循环中执行以下操作。papermill-psymbol$Spapermill_example2.ipynb|jupyter-nbconvert--stdin--no-input--tohtml--outputreport_${S}.html请注意,如果你这样做,你需要打开主笔记本(papermill_example2.ipynb)并编辑参数以调试问题。但是,如果您需要节省磁盘空间并且不需要单独调试每个笔记本的能力,那么这可能更可取。总结Papermill是一个用于参数化和执行Jupyter笔记本的库。您可以使用它通过您能想到的任何参数集来自动化您的笔记本。然后使用nbconvert转换笔记本以提供可读且有用的笔记本版本。notebook自动化还有很多工作要做,但是从Papermill作为执行和参数化notebooks的工具开始是一个很好的构建平台。
