Jupyter进阶教程
原題 | Tutorial: Advanced Jupyter Notebooks
作者 | Benjamin Pryke
譯者 | kbsc13("算法猿的成長(zhǎng)"公眾號(hào)作者)
原文 | https://www.dataquest.io/blog/advanced-jupyter-notebooks-tutorial/
聲明 | 翻譯是出于交流學(xué)習(xí)的目的,歡迎轉(zhuǎn)載,但請(qǐng)保留本文出于,請(qǐng)勿用作商業(yè)或者非法用途
前言
上次介紹了Jupyter 入門教程,這次介紹更多 Jupyter notebook 的使用技巧。
本文主要介紹以下內(nèi)容:
- 介紹一些基本的 shell 命令和方便的魔法命令,包括 debug,計(jì)時(shí)以及執(zhí)行多種語(yǔ)言;
- 探索如 logging、macros、運(yùn)行外部代碼以及 Jupyter 的拓展插件;
- 介紹如何加強(qiáng) Seaborn 模塊的圖表,通過(guò)命令行運(yùn)行,以及使用數(shù)據(jù)庫(kù)。
Shell 命令
在 notebook 中可以直接采用 shell 命令,只需要在 code cell 中,以 ! 開(kāi)頭的都會(huì)被當(dāng)做一個(gè) shell 命令,這在處理數(shù)據(jù)或者文件,管理 Python 包的時(shí)候非常有用。以下是一個(gè)簡(jiǎn)單的示例:
此外,也可以通過(guò)添加 $ 命令在 shell 命令中加入 Python 的變量,如下所示:
[外鏈圖片轉(zhuǎn)存失敗(img-F3ZvGY7u-1564840417547)(https://cai-images-1257823952.cos.ap-beijing.myqcloud.com/shell2.png)]
由于 ! 開(kāi)頭的命令在執(zhí)行完成后就會(huì)被丟棄,因此像 cd 這樣的命令是沒(méi)有效果的。不過(guò),IPython 的魔法命令提供了一個(gè)解決方法。
基本的魔法命令
魔法命令是內(nèi)建于 IPython 核中的非常方便有用的命令,它們專門用于處理特定的任務(wù)。它們雖然看起來(lái)類似 unix 命令,但實(shí)際都是通過(guò) Python 實(shí)現(xiàn)的。魔法命令非常多,但在本文中僅介紹其中一部分魔法命令。
魔法命令也分兩種:
- 行魔法命令(line magics)
- 單元魔法命令(cell magics)
從名字就可以知道,主要是根據(jù)其作用范圍劃分,有的在單行內(nèi)執(zhí)行,有的可以作用多行或者整個(gè)單元內(nèi)。
想了解可用的魔法命令,可以輸入命令 %lsmagic ,輸出結(jié)果如下所示,可以看到確實(shí)分為 line 和 cell 兩類,并且分別給出命令的數(shù)量。
如果想具體了解這些命令的作用,可以上官網(wǎng)查看–https://ipython.readthedocs.io/en/stable/interactive/magics.html。
行魔法命令和單元魔法命令的使用形式也是不同的,行魔法命令是以 % 開(kāi)頭,而單元魔法命令則是 %% 開(kāi)頭。
實(shí)際上 ! 開(kāi)頭是用于 shell 命令的一種比較復(fù)雜的魔法語(yǔ)法,之前說(shuō)的無(wú)法采用類似 cd 的命令,可以采用魔法命令實(shí)現(xiàn),即 %cd、%alias、%env 。
下面介紹更多的例子。
自動(dòng)保存(Autosaving)
首先是 %autosave 命令可以決定 notebook 自動(dòng)保存的時(shí)間間隔,使用例子如下所示,命令后添加時(shí)間間隔參數(shù),單位是秒。
%autosave 60輸出結(jié)果:
Autosaving every 60 seconds顯示 Matplotlib 的圖表
在數(shù)據(jù)科學(xué)中最常用的一個(gè)行魔法命令就是 %matplotlib ,它可以用于顯示 matplotlib 的圖表,使用例子如下:
%matplotlib inline加上參數(shù) inline 可以確保在一個(gè)單元內(nèi)顯示 Matplotlib 的圖表。通常需要在導(dǎo)入 Matplotlib 前就采用這個(gè)行魔法命令,通常都會(huì)放在第一個(gè)代碼單元內(nèi)。
代碼執(zhí)行時(shí)間(Timing Execution)
通常我們都需要考慮代碼的執(zhí)行時(shí)間,在 notebook 中可以有兩個(gè)時(shí)間魔法命令 %time 和 %timeit,它們都有行和單元兩種模式
對(duì)于 %time ,使用例子如下所示:
%timeit 和 %time 的區(qū)別在于,它會(huì)對(duì)給定代碼運(yùn)行多次,并計(jì)算一個(gè)平均時(shí)間,可以通過(guò)添加參數(shù) -n 來(lái)指定運(yùn)行的次數(shù),如果沒(méi)有指定,則會(huì)自動(dòng)選擇一個(gè)最佳的數(shù)量。例子如下所示:
執(zhí)行不同編程語(yǔ)言
在 Jupyter notebook 中可以執(zhí)行不同的編程語(yǔ)言,盡管選擇的核有既定的語(yǔ)言,比如本文例子選擇的就是 Python3 ,但通過(guò)魔法命令可以執(zhí)行不同的編程語(yǔ)言,在 %lsmagic 的輸出結(jié)果也可以找到。
下面是一些使用的例子,包括執(zhí)行 HTML 語(yǔ)言,以及用于顯示數(shù)學(xué)公式的 LaTeX 語(yǔ)言。
當(dāng)然還可以執(zhí)行其他編程語(yǔ)言,包括 Ruby 、markdown 、JavaScript、R 等等。
配置日志(Configuring Logging)
在 Jupyter 中有自定義了如何輸出錯(cuò)誤信息的方法,它可以通過(guò)導(dǎo)入 logging 模塊實(shí)現(xiàn)。
如上圖所示,對(duì)于錯(cuò)誤信息,會(huì)高亮顯示。
另外,logging 模塊的輸出和 print 以及標(biāo)準(zhǔn)的單元輸出是分開(kāi)的,如下圖所示:
之所以會(huì)出現(xiàn)上圖的原因是 Jupyter notebook 會(huì)監(jiān)聽(tīng)標(biāo)準(zhǔn)的輸出流,stdout 和 stderr ,但 print 和單元輸出默認(rèn)是輸出 stdout ,而 logging 則是通過(guò) stderr 輸出。
因此,我們可以對(duì) logging 進(jìn)行配置來(lái)顯示 stderr 的其他類型的信息,比如下圖就顯示了 INFO 和 DEBUG 類型的信息。
logger = logging.getLogger() logger.setLevel(logging.DEBUG)logging.info('This is some information') logging.debug('This is a debug message')還可以自定義信息的輸出格式:
handler = logging.StreamHandler() handler.setLevel(logging.DEBUG)formater = logging.Formatter('%(levelname)s: %(message)s') handler.setFormatter(formater)logger.handlers = [handler]logging.error('An error') logging.warning('An warning') logging.info('An info')注意,如果每次運(yùn)行一個(gè)單元內(nèi)包含代碼 logger.addHandler(handler) 來(lái)添加一個(gè)新的 stream handler ,那么每次輸出都會(huì)多一行額外的信息。我們可以將對(duì)日志的配置放在單獨(dú)的一個(gè)單元內(nèi),或者就如同上述所示代碼,即直接代替所有現(xiàn)在的 handler ,不采用 addHandler ,而是 logger.handlers = [handler]。這種做法可以移除默認(rèn)的 handler 。
當(dāng)然也可以將日志信息保存到文件中,代碼如下所示,采用 FileHandler 而非 StreamHandler 。
handler = logging.FileHandler(filename='important_log.log', mode='a')最后,這里采用的日志跟通過(guò) %config Application.log_level='INFO' 設(shè)置的日志等級(jí)是不相同的,通過(guò) %config 配置的是 Jupyter 輸出到當(dāng)前運(yùn)行 Jupyter 的終端上的日志信息。
拓展
Jupyter 是一個(gè)開(kāi)源的工具,因此有很多開(kāi)發(fā)者開(kāi)發(fā)了很多拓展插件,具體可以查看:
https://github.com/ipython/ipython/wiki/Extensions-Index
在后面介紹的使用數(shù)據(jù)庫(kù),就采用了插件 ipython-sql,還有就是包含了拼寫檢查、代碼折疊等等功能的一個(gè)拓展插件 Github:
https://github.com/ipython-contrib/jupyter_contrib_nbextensions
安裝這些插件可以通過(guò)下面的命令
pip install ipython-sql pip install jupyter_contrib_nbextensions jupyter contrib nbextension install --user jupyter nbextension enable spellchecker/main jupyter nbextension enable codefolding/main加強(qiáng) Seaborn 的圖表
Jupyter notebook 的最常見(jiàn)的一種應(yīng)用就是用于繪制圖表。但 Python 的最常見(jiàn)繪圖庫(kù) Matplotlib 在 Jupyter 中并未能給出很吸引人的結(jié)果,這可以通過(guò) Seaborn 進(jìn)行美化并添加一些額外的功能。
如果沒(méi)有安裝 seaborn,可以通過(guò)命令 pip install seaborn ,或者在 jupyter 中,根據(jù)開(kāi)始介紹的 shell 命令執(zhí)行方式–!pip install seaborn ,安裝完后,就可以先導(dǎo)入必須的庫(kù)和數(shù)據(jù):
%matplotlib inline import matplotlib.pyplot as plt import seaborn as sns data = sns.load_dataset("tips")通過(guò) seaborn 提供的簡(jiǎn)單的數(shù)據(jù)集,這里采用的 tips 是一個(gè) pandas 的 DataFrame 格式數(shù)據(jù)集,內(nèi)容是來(lái)自一個(gè)酒吧或者飯店的賬單信息。
通過(guò) data.head() 可以展示前 5 條數(shù)據(jù),并查看屬性信息。
采用 Matplotlib 繪制 total_bill 和 tip 的關(guān)系圖:
plt.scatter(data.total_bill, data.tip);添加 Seaborn 也是很簡(jiǎn)單,如下所示,通過(guò) seaborn 設(shè)置了一個(gè) darkgrid 的樣式
sns.set(style="darkgrid") plt.scatter(data.total_bill, data.tip);seaborn 總共有 5 種樣式:darkgrid, whitegrid, dark, white, and ticks。
實(shí)際上我們也可以單獨(dú)采用 seaborn 的繪圖函數(shù),如下所示:
sns.scatterplot(x="total_bill", y="tip", data=data);上圖可以添加每個(gè)坐標(biāo)的標(biāo)題信息以及對(duì)每個(gè)數(shù)據(jù)點(diǎn)有一個(gè)提升的標(biāo)記。Seaborn 還可以自動(dòng)根據(jù)數(shù)據(jù)的類型進(jìn)行劃分,即可以再添加一個(gè)維度,這里我們可以再添加屬性 smoker 作為參數(shù) hue ,表示數(shù)據(jù)點(diǎn)的顏色:
sns.scatterplot(x="total_bill", y="tip", hue="smoker", data=data);[外鏈圖片轉(zhuǎn)存失敗(img-7BaKnTb6-1564840417651)(https://cai-images-1257823952.cos.ap-beijing.myqcloud.com/seaborn5.png)]
添加 smoker 后,我們可以看到每個(gè)數(shù)據(jù)點(diǎn)都根據(jù)是否劃分為兩種顏色的數(shù)據(jù)點(diǎn),展示的信息就更加豐富了。我們?cè)龠M(jìn)一步,加入屬性 size 作為顏色的劃分,而 smoker 作為樣式,如下所示:
sns.scatterplot(x="total_bill", y="tip", hue="size", style="smoker", data=data);seaborn 可以繪制更多更好看的圖表,更多的例子可以查看其官網(wǎng):
https://seaborn.pydata.org/examples/index.html
宏命令(Macros)
很多時(shí)候,我們可能會(huì)重復(fù)做相同的任務(wù),比如每次創(chuàng)建一個(gè)新的 notebook,都需要導(dǎo)入相同的一堆第三方庫(kù),對(duì)每個(gè)數(shù)據(jù)集都進(jìn)行的統(tǒng)計(jì)方法,或者繪制相同類型的圖表。
在 Jupyter 里可以將一些代碼片段保存為可執(zhí)行的宏命令,并且能用在所有的 notebooks 里。這種操作可能對(duì)其他閱讀使用你的 notebook 的人來(lái)說(shuō)并不是很友好的方式,但對(duì)你來(lái)說(shuō),確實(shí)會(huì)是非常方便以及減輕工作量的方法。
宏命令也是代碼,因此也可以包含變量。下面開(kāi)始介紹示例
首先是寫好一個(gè)代碼單元,主要作用就是輸出 Hello, name!,其中 name 也是定義好的一個(gè)變量,然后利用命令 %macro 來(lái)保存宏命令,名字是 __hello_world ,而 28 表示的就是上一個(gè)運(yùn)行順序?yàn)?28 的代碼單元,即 In [28] 對(duì)應(yīng)的代碼單元,然后 %store 是保存宏命令。
載入宏命令的操作如下,還是采用命令 %store ,但需要加上參數(shù) -r ,以及宏命令的名字。
如果修改在宏命令中采用的變量,其輸出結(jié)果也會(huì)改變:
name = 'Ben' __hello_world輸出結(jié)果:
Hello, Ben!宏命令還可以實(shí)現(xiàn)更多的操作,具體還是可以查看官網(wǎng)。
執(zhí)行外部代碼
在 Jupyter 還可以加載和運(yùn)行外部代碼,也就是 .py 代碼文件。這里需要采用的命令分別是 %load 和 %run。
我們先創(chuàng)建一個(gè)新的代碼文件–imports.py ,其包含內(nèi)容如下:
import pandas as pd import numpy as np import matplotlib.pyplot as plt然后在 jupyter 中加載該代碼文件:
%load imports.py運(yùn)行結(jié)果如下:
接著我們創(chuàng)建一個(gè)新的代碼文件–triangle_hist.py ,代碼如下,繪制一個(gè)三角形直方圖。
import numpy as np import matplotlib.pyplot as plt import seaborn as sns sns.set(style="darkgrid")if __name__ == '__main__':h = plt.hist(np.random.triangular(0, 5, 9, 1000), bins=100, linewidth=0)plt.show()然后調(diào)用命令 %run 運(yùn)行:
[外鏈圖片轉(zhuǎn)存失敗(img-AjWf6afb-1564840417681)(https://cai-images-1257823952.cos.ap-beijing.myqcloud.com/executing_external_code2.png)]
此外,還可以傳遞參數(shù)給腳本,只需要在代碼文件名后添加即可,比如 %run my_file.py 0 "Hello, World!",或者是傳遞變量名,如 %run $filename {arg0} {arg1} ,還可以添加 -p 來(lái)通過(guò) Python 的分析器運(yùn)行代碼,具體可以參考下面兩個(gè) stackoverflow 上的回答:
- https://stackoverflow.com/a/14411126/604687
- https://stackoverflow.com/questions/582336/how-can-you-profile-a-python-script/582337#582337
腳本運(yùn)行
Jupyter notebook 最強(qiáng)大的作用是其交互式的流程,但它也可以在非交互式的模式下運(yùn)行,即可以通過(guò)腳本或者命令行形式運(yùn)行 jupyter notebook。
命令行的基本語(yǔ)法如下:
jupyter nbconvert --to <format> notebook.ipynb其中 nbconvert 是用于將 notebook 轉(zhuǎn)換為其他形式的一個(gè) API 接口,比如 PDF、HTML、python 腳本(即 .py 文件),甚至 LaTeX 文件。
比如,需要將 notebook 轉(zhuǎn)換為 PDF 形式:
jupyter nbconvert --to pdf notebook.ipynb這個(gè)操作將生成一個(gè) pdf 文件–notebook.pdf ,當(dāng)然如果要實(shí)現(xiàn)轉(zhuǎn)換為 PDF ,還需要安裝一些必須的庫(kù)–pandoc 和 LaTeX,安裝方法可以查看:
https://stackoverflow.com/a/52913424/604687
默認(rèn)情況下,nbconvert 并不會(huì)執(zhí)行 notebook 里的代碼,但可以添加 --execute 來(lái)讓其運(yùn)行代碼:
jupyter nbconvert --to pdf --execute notebook.ipynb另外,還可以添加 --allow-errors 來(lái)讓 nbconvert 會(huì)輸出代碼中的錯(cuò)誤信息,并且不會(huì)因?yàn)槌霈F(xiàn)錯(cuò)誤而中斷轉(zhuǎn)換過(guò)程:
jupyter nbconvert --to pdf --execute --allow-errors notebook.ipynb使用數(shù)據(jù)庫(kù)
要在 jupyter 中使用數(shù)據(jù)庫(kù),首先需要安裝 ipython-sql :
pip install ipython-sql安裝好后,首先輸入以下魔法命令來(lái)加載 ipython-sql 。
%load_ext sql接著就是連接到一個(gè)數(shù)據(jù)庫(kù):
%sql sqlite://輸出:
'Connected: @None'這里是連接到一個(gè)臨時(shí)的數(shù)據(jù)庫(kù),你也可以指定連接到你的數(shù)據(jù)庫(kù),可以按照官網(wǎng)(https://docs.sqlalchemy.org/en/latest/core/engines.html#database-urls)的語(yǔ)法進(jìn)行連接:
dialect+driver://username:password@host:port/database比如可以是類似 postgresql://scott:tiger@localhost/mydatabase,也就是 driver 就是 postgresql ,usename 是 scott ,password 是 tiger,host 是 localhost ,然后 database 是 mydatabse .
接下來(lái)就是快速采用之前用 Seaborn 加載的 tips 的數(shù)據(jù)集來(lái)構(gòu)建我們的數(shù)據(jù)庫(kù):
接下來(lái)就可以對(duì)數(shù)據(jù)進(jìn)行一些查詢的操作,如下所示,這里需要用到多行魔法命令形式 %% :
還可以進(jìn)行更復(fù)雜的查詢操作:
更多的例子可以查看 https://github.com/catherinedevlin/ipython-sql
小結(jié)
對(duì)比原文,其實(shí)刪除了部分內(nèi)容,比如腳本運(yùn)行 jupyter 部分,自定義 jupyter 的樣式,然后數(shù)據(jù)庫(kù)部分也有所刪減,主要是原文的代碼總是缺失一部分內(nèi)容。
參考
- https://github.com/catherinedevlin/ipython-sql
- https://github.com/ipython-contrib/jupyter_contrib_nbextensions
- https://github.com/mwaskom/seaborn-data
- https://stackoverflow.com/a/14411126/604687
- https://stackoverflow.com/questions/582336/how-can-you-profile-a-python-script/582337#582337
- https://nbconvert.readthedocs.io/en/latest/install.html#installing-nbconvert
- https://stackoverflow.com/a/52913424/604687
- https://github.com/catherinedevlin/ipython-sql
最后本文的代碼都上傳到 Github 上了:
https://github.com/ccc013/Python_Notes/blob/master/Projects/jupyter_notebook_tutorial/jupyter_advanced_tutorial.ipynb
歡迎關(guān)注我的微信公眾號(hào)–算法猿的成長(zhǎng),或者掃描下方的二維碼,大家一起交流,學(xué)習(xí)和進(jìn)步!
總結(jié)
以上是生活随笔為你收集整理的Jupyter进阶教程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Python-100 练习题 03 完全
- 下一篇: 这7款文本编辑器,程序员都应该知道