1.7 Jupyter中的魔法函数
Jupyter的魅力之处,除了体现在能提供丰富多彩的格式化文本显示,还体现在它提供了很多好用的函数。这些函数如同有魔力一般,故也被称为魔法函数(Magic Function)。所谓魔法函数,实际上是IPython预先定义好的具备特定功能的函数被放到Jupyter中使用罢了。
请注意,这是IPython特有的函数,并非Python的内置函数,因此脱离IPython的使用环境(如使用Pycharm或Python自带的IDLE开发环境等),这些函数是无法被解析运行的。
在图1-22中,第14行和第16行就分别涉及了两个魔法函数:%timeit和%matplotlib inline,后面我们会分别介绍它们。
魔法函数分两种:一种是面向行的(line magic),以一个百分号(%)开头,其作用范围就是使用这个魔法函数的当前行,里面可添加其他正常代码(如图1-22中的第14行);另一种是面向整个块的(即Jupyter中左侧给出编号In[n]:的一块区域,这里n为某个具体的编号),其作用范围是整个块。
下面我们简单介绍几个最常见的魔法函数。
1.7.1 %lsmagic函数
%lsmagic函数可以列出(list,简写ls)所有魔法函数。如果我们想使用一个魔法函数,却忘记函数名如何写时,就可以使用%lsmagic来查询(在代码框内输入%lsmagic后按Shift+Enter组合键执行即可),如图1-29所示。
图1-29 Jupyter中的各种魔法函数
1.7.2 %matplotlib inline函数
图1-22的第16行代码中出现过%matplotlib inline函数,它的含义就是告诉Ipython,我们的绘图模式是内嵌(inline)模式,即将绘图直接显示在当前的网页上。有了这个魔法函数,图1-22所示代码的第21行plt.show()其实是可以省略的,读者朋友将其用注释形式去掉,然后尝试再次运行代码,可查看结果有无变化。
其实,这个魔法函数的后置参数“inline”有一个“对标”参数—qt,如果我们使用这个参数,即%matplotlib qt,则表示代码构造的图形是通过独立窗口显示的。在独立窗口中可支持图形的缩放、拖曳及被另存为多种格式的图形文件(如.jpg、.png和.pdf等)。读者朋友可将图1-22中的第16行代码修改为的%matplotlib qt并再次运行,感性认识这两个参数带来的不同。
1.7.3 %timeit函数
魔法函数%timeit的功能是为某行代码的执行提供计时服务,这在评估机器学习算法的性能(特别是评估运行时间)时特别有用。例如,如果我们想对图1-22中的第14行代码的运行时间进行计时,则可以如下操作。
按Shift+Enter组合键执行,结果如下。
上述输出结果的意思是,对于代码“area=(40 * np.random.rand(20))**2”运行7轮,每轮运行1000个循环,然后求得均值为6.6微秒,方差为1.28微秒。
如果我们想运行10轮而非7轮,该怎么办呢?这时就需要为魔法函数添加参数了,具体如下。
需要注意的是,参数选项“-n10”中的“-n”和“10”中间并没有空格。图1-29列出了如此多魔法函数,我们怎么才能知道某个魔法函数的具体用法呢?最简单的办法就是在Jupyter中创建一个新的单元格,然后输入该魔法函数,最后追加一个问号(?),注意函数名和问号之间没有空格,如下所示。
然后按Ctrl+Enter组合键运行这个单元格。
假设某个代码块正好就是一个算法的实现,现在我们想对整个代码块的运行进行计时,而不是对某一行代码的运行计时,该如何做呢?
这时,就需要利用%timeit的姊妹函数—块魔法函数%%timeit,即timeit前面有两个%。如前所述,它的适用范围是整个代码块,因此通常会把这个魔法函数放在某个代码块的首行。
1.7.4 %%writefile函数
我们知道,Jupyter是一个集才华(代码编写)和颜值(图文文档显示)于一身的编程工具。但有时,如在生产环境中,我们还想把调试好的Python代码单独拎出来操作,这时该怎么办呢?
当然,我们可以采用复制的方式,把Jupyter代码块中的代码一块一块地复制到一个IDE(如Spyder)的新建文件中,然后保存为我们所需要的Python源文件。但实际上,Jupyter已经替我们考虑到这个需求。魔法函数%%writefile就是做这项工作的。见名知意,这个魔法函数的主要功能是把整个代码块中的Python代码保存为一个.py文件。
通过该魔法函数前端的两个百分号(%%)就可以看出,这是一个作用域为整块代码的魔法函数。%%writefile后面跟的参数是一个具体的Python文件名。假设我们想保存图1-22所示的代码块中的Python代码,就可以在代码块的首行添加如下代码。
然后,按Ctrl+Enter组合键运行单元格,这个myFirstBook.py源文件就默认保存在与*.ipynb(Jupyter文件)相同的路径下。当然,我们可以为其添加一个非默认路径,如%%writefile/Users/yhilly/ Documents/myFirstBook.py,在这种情况下,单元格执行之后,myFirstBook.py就被存储在“/Users/yhilly/Documents/”路径下。读者也可以单击Jupyter的菜单栏【File】→【Download as】,有多种文件格式可供选择,可将编写好的代码保存到本地。
1.7.5 其他常用的魔法函数
下面我们列出其他常用的魔法函数,如表1-1所示,更多详细使用方法,可参阅IPython的官方文档。
表1-1 其他常用的魔法函数
当然,Jupyter的功能及使用技巧远远不止上面这些,在以后的用得着的日子里,我们还需要边用边摸索,这里就不一一介绍了。
1.7.6 在Jupyter中执行shell命令
我们知道,shell是一种在命令行执行的与计算机进行文本交互的命令方式。一般而言,当我们正在使用Python编译器且需要用到命令行工具时,要在shell和IDLE之间不断切换。
但在Jupyter环境下,一切都显得浑然天成。在代码单元格里,直接在命令之前添加一个“!”(注意:请用英文的惊叹号)就能执行shell命令,如图1-30所示。
图1-30 在Jupyter中执行shell命令
我们可以把shell命令返回的结果当作参数传递给Python变量,如图1-31所示。
图1-31 将shell命令返回的结果传递给Python变量