今天为大家分享一篇文章,总结了 28 个 Jupyter 中的实用技巧,本篇文章是上篇,为大家介绍了前 14 条,希望大家可以让 Jupyter 成为你的一大助力。
Jupyter Notebook
Jupyter notebook 的前身是 IPython notebook,一个可以帮你创建具有优秀可读性分析结果的灵活工具,因为你可以轻松的将代码,图片,注释,公式和绘图结果放在一起。在这篇文章中,我们收集了一些最热门的 Jupyter notebook 小技巧,来帮助你快速的成为一个 Jupyter 的熟练老鸟。
「这篇文章是基于 Alex 的博客[1] 这篇博客。我们在在此基础上进行了扩展,并且会继续更新下去——如果你有任任何建议也请让我们知道[2]。感谢 Alex 让我们在这里再参考整理他的文章。」
Jupyter 非常易于扩展,支持多种编程语言,并且很容易运行在你的计算机或者几乎任何服务器上——你只需要有 ssh 或者 http 权限。最棒的点是:它完全免费。现在让我们进入到这 28 条(还在继续统计中)Jupyter notebook 的小技巧中吧!
Jupyter 项目诞生于 IPython 项目,然后逐渐发展为一个支持多种语言的 notebook,因此它在历史上的原名是 IPython notebook。这个名字 Jupyter 来自于三个核心语言的间接缩写:「JU」lia、「PYT」hon 和 「R」,同时也从火星(Jupiter)一词获得了灵感。
当我们在 Jupyter 中使用 python 工作时,IPython 的内核会被使用,这让我们可以在我们的 Jupyter notebook 中很容易的去访问一些 IPython 的特性(后面我们会详细介绍!)
接下来我们会给你展示 28 个诀窍和技巧,让你更容易的使用 Jupyter 来完成工作。
1. 键盘快捷键
众所周知,键盘快捷键可以节约你的大量时间。Jupyter 在顶部的菜单栏中存储了一个键盘快捷键的列表:Help > Keyboard Shortcuts
,或者在命令模式(后面我们会详细介绍)按下 H
也可以。每次你更新 Jupyter 都需要检查一下这个,因为会持续添加新的快捷键进来。
另外一种可以访问键盘快捷键,并且方便的学习它们的方法是使用命令行界面:Cmd + Shift + P
(在 Linux 和 Windows 上面则是 Ctrl + Shift + P
)。这个对话框可以帮助你通过名称运行任何命令——如果你不知道某个操作的键盘快捷键,或者你想要执行的操作没有快捷键,那么这个方法就会非常有用。它的功能类似于 Mac 上的 Spotlight search,一旦你开始使用它,你将难以想象没有它该如何生活。
推荐一些我比较喜欢的:
Esc
会使你进入命令模式,此时你可以通过方向键来导航你的 notebook。当在命令模式时:
A
键会在当前 cell 前面插入一个新的 cell,B
键则是在后面进行插入。M
键改变当前的 cell 为 Markdown 格式,Y
键将其换回代码格式。D + D
(双击该键)可以删除当前的 cell
Enter
可以从命令模式返回到当前 cell 的编辑模式,Shift + Tab
将会展示你刚刚输入的代码块的文档——你可以通过一直按这个快捷键来循环展示几种文档模式。Ctrl + Shift + -
可以将当前代码块从你的光标位置,拆分为两个。Esc + F
发现并替换你的代码,但是并不会输出。Esc + O
切换当前 cell 的输出。选择多个 cell:
Shift + J
或者Shift + Down
向下选择下一个 cell。你也可以通过使用Shift + K
或者Shift + Up
来向上选择对应的 cell。- 当多个 cell 被选择时,你就可以一次性删除/复制/剪切/粘贴/运行它们。当你想要在 notebook 中移动一部分内容时,这就很有帮助。
- 你也可以使用
Shift + M
来合并多个 cell。
2. 漂亮的展示变量
关于漂亮的第一点是众所周知的。当完成一个 Jupyter cell 时,如果是一个变量名或者是一个没有将输出赋值的语句,Jupyter 在没有 print 语句的情况下依然会展示该变量。这一点在处理 Pandas 的 DataFrames 时尤其有用,对应的输出会被整齐的展示为一个表格。
比较鲜为人知的是,你可以调整 ast_note_interactivity
内核选项,来使得 Jupyter 可以在自己的每行变量或语句上执行此操作,所以你可以一次性看到多个语句的变量值。
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
from pydataset import data
quakes = data('quakes')
quakes.head()
quakes.tail()
lat | long | depth | mag | stations | |
---|---|---|---|---|---|
1 | -20.42 | 181.62 | 562 | 4.8 | 41 |
2 | -20.62 | 181.03 | 650 | 4.2 | 15 |
3 | -26.00 | 184.10 | 42 | 5.4 | 43 |
4 | -17.97 | 181.66 | 626 | 4.1 | 19 |
5 | -20.42 | 181.96 | 649 | 4.0 | 11 |
lat | long | depth | mag | stations | |
---|---|---|---|---|---|
996 | -25.93 | 179.54 | 470 | 4.4 | 22 |
997 | -12.28 | 167.06 | 248 | 4.7 | 35 |
998 | -20.13 | 184.20 | 244 | 4.5 | 34 |
999 | -17.40 | 187.80 | 40 | 4.5 | 14 |
1000 | -21.59 | 170.56 | 165 | 6.0 | 119 |
如果你想要在所有的 Jupyter(Notebook 和控制台)例子中设置这种形式,可以按照下面的方法简单的创建一个文件 ~/.ipython/profile_default/ipython_config.py
。
c = get_config()
# Run all nodes interactively
c.InteractiveShell.ast_node_interactivity = "all"
3. 方便的链接文档
在内置的 Help
菜单中,你可以发现一些常见库在线文档的便捷链接,包括 NumPy,Pandas,SciPy 和 Matplotlib。
不要忘记在一个库,方法或者变量前面附加 ?
,你就可以访问文档来获取相应语法的快速参考。
?str.replace()
Docstring:
S.replace(old, new[, count]) -> str
Return a copy of S with all occurrences of substring
old replaced by new. If the optional argument count is
given, only the first count occurrences are replaced.
Type: method_descriptor
4. 在 notebook 中绘图
在你的 notebook 中有一些选项可以生成绘图结果。
- matplotlib[3](事实上已成为标准选项),通过
%matplotlib inline
来激活。这里推荐一个 Dataquest 上的 Matplotlib 教程[4]。 %matplotlib notebook
提供了交互性,但是略微有点慢,因为渲染是在服务端完成的。- Seaborn[5] 是建立在 Matplotlib 之上的,可以非常容易的构建一些更具有吸引力的图形。只需要导入 Seaborn,无需任何代码上的修改,你的 matplotlib 图形就可以变得“更漂亮”。
- mpld3[6] 提供了对 matplotlib 代码替代的渲染器(使用 d3)。很不错,尽管还不够完整。
- bokeh[7] 是一个构建交互图形更好的选项。
- plot.ly[8] 可以生成漂亮的图形——这在过去只是一个付费服务,但是最近开源了。
- Altair[9] 是一个相对较新的 python 可视化库。它易于使用并且看一看做出很漂亮的图形,但是在自定义定制图形的能力上不如 Matplotlib 强大。
5. IPython 魔术命令
上面我们提到的 %matplotlib inline
就是 IPython 魔术命令的一个例子。由于是基于 IPython 内核,Jupyter 可以从 IPython 内核中访问所有魔术命令,它们可以让你的生活轻松很多。
# 这将会展示所有魔术命令
%lsmagic
Available line magics:
%alias %alias_magic %autocall %automagic %autosave %bookmark %cat %cd %clear %colors %config %connect_info %cp %debug %dhist %dirs %doctest_mode %ed %edit %env %gui %hist %history %killbgscripts %ldir %less %lf %lk %ll %load %load_ext %loadpy %logoff %logon %logstart %logstate %logstop %ls %lsmagic %lx %macro %magic %man %matplotlib %mkdir %more %mv %notebook %page %pastebin %pdb %pdef %pdoc %pfile %pinfo %pinfo2 %popd %pprint %precision %profile %prun %psearch %psource %pushd %pwd %pycat %pylab %qtconsole %quickref %recall %rehashx %reload_ext %rep %rerun %reset %reset_selective %rm %rmdir %run %save %sc %set_env %store %sx %system %tb %time %timeit %unalias %unload_ext %who %who_ls %whos %xdel %xmode
Available cell magics:%%! %%HTML %%SVG %%bash %%capture %%debug %%file %%html %%javascript %%js %%latex %%perl %%prun %%pypy %%python %%python2 %%python3 %%ruby %%script %%sh %%svg %%sx %%system %%time %%timeit %%writefile
Automagic is ON, % prefix IS NOT needed for line magics.
我建议你浏览 所有 IPython 魔术方法的文档[10],你将无疑会发现一些对你有帮助的内容。下面介绍一些我比较喜欢的:
6. IPython Magic - %env:设置环境变量
你可以在你的 notebook 中管理环境变量,而无需重启 jupyter 服务进程。一些库(例如 theano)使用环境变量来控制性能,%env 是最方便的方法。
# 不带任何参数运行 %env 会列出所有环境变量
# 下面的语句设置环境变量
%env OMP_NUM_THREADS=4
env: OMP_NUM_THREADS=4
7. IPython Magic - %run:执行 python 代码
%run
可以从 .py 文件中执行 python 代码——这是大量文档证明的做法。事实上很少有人知道,它同样可以执行其它 jupyter notebook,这个相当有用。
注意使用 %run
并不等同于导入一个 python 包。
# 这个方法会执行并且输出给定 notebook 中的所有代码块
%run ./two-histograms.ipynb
8. IPython Magic - %load:从一个外部脚本中插入代码
这个会用一个外部脚本来替换当前 cell 中的内容。你可以使用一个你电脑上的文件作为替换源,也可以对应替换成一个 URL。
# Before Running
%load ./hello_world.py
# After Running
# %load ./hello_world.py
if __name__ == "__main__":
print("Hello World!")
Hello World!
9. IPython Magic - %store:在不同 notebook 中传递变量
%store
命令可以让你在两个不同的 notebook 中传递变量。
data = 'this is the string I want to pass to different notebook'
%store data
del data # This has deleted the variable
Stored 'data' (str)
现在,在另外一个 notebook 中...
%store -r data
print(data)
this is the string I want to pass to different notebook
10. IPython Magic - %who:展示全部变量
不带任何参数的 %who
命令会展示所有全局作用域中的变量。传入一个参数例如 str
将会只列出对应的类型。
one = "for the money"
two = "for the show"
three = "to get ready now go cat go"
%who str
one three two
11. IPython Magic - Timing
关于时间方面有两个 IPython 魔术命令比较常用——%%time
和 %timeit
。当你有一些运行比较慢的代码,你又尝试去定位问题时,这些就非常有用了。
%%time
会为一个单独的代码块给出运行信息。
%%time
import time
for _ in range(1000):
time.sleep(0.01) # sleep for 0.01 seconds
CPU times: user 21.5 ms, sys: 14.8 ms, total: 36.3 ms Wall time: 11.6 s
%%timeit
使用 python 的 timeit 模块[11],会运行一个语句 100,000 次(默认值)并且提供最快的三次运行的平均时间。
import numpy
%timeit numpy.random.normal(size=100)
The slowest run took 7.29 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 5.5 µs per loop
12. IPython Magic - %%writefile 和 %pycat:导出 cell 内容/展示外部脚本内容
使用 %%writefile
魔术命令将 cell 中的内容保存到一个外部文件中。%pycat
恰恰相反,可以在语法高亮的基础上为你展示(以弹出的方式)外部文件的内容。
%%writefile pythoncode.py
import numpy
def append_if_not_exists(arr, x):
if x not in arr:
arr.append(x)def some_useless_slow_function():
arr = list()
for i in range(10000):
x = numpy.random.randint(0, 10000)
append_if_not_exists(arr, x)
Writing pythoncode.py
%pycat pythoncode.py
import numpy
def append_if_not_exists(arr, x):
if x not in arr:
arr.append(x)def some_useless_slow_function():
arr = list()
for i in range(10000):
x = numpy.random.randint(0, 10000)
append_if_not_exists(arr, x)
13. IPython Magic - %prun:展示每个函数中你程序的消耗时间
使用 %prun statement_name
会给你返回一个有序的表,内容包括语句中每个内部函数被调用的次数,每次调用所用的时间,以及所有函数运行的累计时间。
%prun some_useless_slow_function()
26324 function calls in 0.556 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
10000 0.527 0.000 0.528 0.000 :2(append_if_not_exists)
10000 0.022 0.000 0.022 0.000 {method 'randint' of 'mtrand.RandomState' objects}
1 0.006 0.006 0.556 0.556 :6(some_useless_slow_function)
6320 0.001 0.000 0.001 0.000 {method 'append' of 'list' objects}
1 0.000 0.000 0.556 0.556 :1()
1 0.000 0.000 0.556 0.556 {built-in method exec}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
14. IPython Magic - 用 %pdb 调试
Jupyter 有自己的 The Python Debugger (`pdb`)[12] 接口。这就使得它能够进入函数内部,并且挖掘具体发生了什么。
你可以 在这里[13] 浏览可用的 pdb
命令的具体内容。
%pdb
def pick_and_take():
picked = numpy.random.randint(0, 1000)
raise NotImplementedError()
pick_and_take()
Automatic pdb calling has been turned ON
--------------------------------------------------------------------
NotImplementedError Traceback (most recent call last)
in ()
5 raise NotImplementedError()
6
----> 7 pick_and_take()
in pick_and_take()
3 def pick_and_take():
4 picked = numpy.random.randint(0, 1000)
----> 5 raise NotImplementedError()
6
7 pick_and_take()
NotImplementedError:
> (5)pick_and_take()
3 def pick_and_take():
4 picked = numpy.random.randint(0, 1000)
----> 5 raise NotImplementedError()
6
7 pick_and_take()
ipdb>
译者小结
今天我们先介绍这 14 个小技巧,下篇文章我们再继续介绍后面的 14 个 Jupyter 小技巧,包括与外部 shell 交互,使用 LaTeX,在不同的内核上运行等。我们下篇再见哟~~
Reference
[1]Alex 的博客: http://arogozhnikov.github.io/2016/09/10/jupyter-features.html
[2]让我们知道: https://twitter.com/dataquestio
[3]matplotlib: http://matplotlib.org/
[4]Matplotlib 教程: https://www.dataquest.io/blog/matplotlib-tutorial/
[5]Seaborn: http://seaborn.pydata.org/
[6]mpld3: https://github.com/mpld3/mpld3
[7]bokeh: http://bokeh.pydata.org/en/latest/
[8]plot.ly: https://plot.ly/
[9]Altair: https://github.com/altair-viz/altair
[10]所有 IPython 魔术方法的文档: http://ipython.readthedocs.io/en/stable/interactive/magics.html
[11]timeit 模块: https://docs.python.org/3.5/library/timeit.html
[12]The Python Debugger (pdb
): https://docs.python.org/3.5/library/pdb.html
pdb 可用命令: https://docs.python.org/3.5/library/pdb.html#debugger-commands
往期回顾
一篇长文学懂 pytorch
一个例子告诉你,在 pytorch 中应该如何并行生成数据
一篇长文学懂入门推荐算法库:surprise
推荐系统教程:八篇文章给你梳理推荐系统的技术