- 利用Python進行數據分析(原書第2版)
- (美)韋斯·麥金尼
- 3905字
- 2019-01-05 06:07:21
2.2 IPython基礎
本節,我們將帶你運行IPython命令行和Jupyter notebook,并介紹一些核心概念。
2.2.1 運行IPython命令行
你可以像啟動標準Python解釋器那樣,通過ipython命令啟動IPython命令行:
$ ipython Python 3.6.0 | packaged by conda-forge | (default, Jan 132017, 23:17:12) Type "copyright", "credits" or "license" for more information. IPython 5.1.0-- An enhanced Interactive Python. ? -> Introduction and overview of IPython's features. %quickref -> Quick reference. help -> Python's own help system. object? -> Details about 'object', use 'object? ? ' for extra details. In [1]: a = 5 In [2]: a Out[2]: 5
你可以將Python語句輸入命令行,然后按下回車鍵運行。當你在IPython中僅輸入一個變量名,它會返回一個表示該對象的字符串:
In [5]: import numpy as np In [6]: data = {i : np.random.randn() for i in range(7)} In [7]: data Out[7]: {0: -0.20470765948471295, 1: 0.47894333805754824, 2: -0.5194387150567381, 3: -0.55573030434749, 4: 1.9657805725027142, 5: 1.3934058329729904, 6: 0.09290787674371767}
前兩行是Python語句,其中第二行創建了一個名為data的變量,并引用了新建的Python字典。最后一行在控制臺中打印了data的值。
與常見的print打印語句不同,IPython中大多數Python對象被格式化為更可讀、更美觀的形式。如果使用print方法在標準Python解釋器中打印data變量,可讀性會差一些:
>>> from numpy.random import randn >>> data = {i : randn() for i in range(7)} >>> print(data) {0: -1.5948255432744511, 1: 0.10569006472787983, 2: 1.972367135977295, 3: 0.15455217573074576, 4: -0.24058577449429575, 5: -1.2904897053651216, 6: 0.3308507317325902}
IPython還提供執行任意代碼塊(通過復制粘貼實現)和整個Python腳本的功能。你也可以使用Jupyter notebook來處理大段的代碼塊,后續內容會有介紹。
2.2.2 運行Jupyter notebook
Jupyter項目中的主要組件就是notebook,這是一種交互式的文檔類型,可以用于編寫代碼、文本(可以帶標記)、數據可視化以及其他輸出。Jupyter notebook與內核交互,內核是編程語言的交互式計算協議的實現。Python的Jupyter內核使用IPython系統進行內部活動。
需要啟動Jupyter時,可以在終端中運行jupyter notebook命令:
$ jupyter notebook [I 15:20:52.739 NotebookApp] Serving notebooks from local directory: /home/wesm/code/pydata-book [I 15:20:52.739 NotebookApp] 0 active kernels [I 15:20:52.739 NotebookApp] The Jupyter Notebook is running at: http://localhost:8888/ [I 15:20:52.740 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation). Created new window in existing browser session.
在很多平臺上,Jupyter會自動打開你的默認網絡瀏覽器(除非你使用了--no-browser命令)。你可以通過http地址來瀏覽notebook,地址是http://localhost:8888/。圖2-1是谷歌Chrome瀏覽器中的效果。
很多人使用Jupyter作為本地計算環境,但它其實也可以部署在服務器端,遠程訪問。我不會介紹這些內容,但如果有需要的話,建議你在網上搜索相關的主題。

圖2-1:Jupyter notebook登錄頁面
點擊新建按鈕選擇“Python 3”或者“conda[default]”即可新建一個筆記本,然后你應該就可以看到如圖2-2所示的內容。如果這是你第一次使用,請嘗試點擊空的代碼“單元”,輸入一行Python代碼,然后按下Shift-Enter來執行。

圖2-2:Jupyter新建筆記本視圖
當你保存筆記本的時候(在File菜單下有“Save and Checkpoint”選項),會自動生成一個后綴名為.ipynb的文件。這種文件格式會包含筆記本中當前的所有內容(包括已經產生的代碼輸出)。這些內容可以被其他的Jupyter用戶載入、編輯。要載入一個已經存在的筆記本,可以將文件放置在你啟動命令行進程的路徑下(或者是該路徑下的子文件夾中),然后在登錄頁面雙擊文件名。你可以試試我在GitHub上的筆記本倉庫wesm/pydata-book。見圖2-3。

圖2-3:通過Jupyter打開已經存在的筆記本
盡管Jupyter notebook提供了與IPython命令行不同的體驗,但幾乎所有的命令和工具都可以在兩種環境下使用。
2.2.3 Tab補全
從表面上看,IPython只是看起來與標準Python解釋器(通過python命令啟動)有一些裝飾性的區別。相較于標準Python命令行,IPython的提升之一就是tab補全功能,通常該功能在IDE或者其他交互式計算分析環境中才有。當在命令行輸入表達式時,按下Tab鍵即可為任意變量(對象、函數等)搜索命名空間,與你目前已輸入的字符進行匹配:
In [1]: an_apple = 27 In [2]: an_example = 42 In [3]: an<Tab> an_apple and an_example any
在上述示例中,請注意IPython同時列出了我已定義的兩個變量、關鍵字and和內建函數any。當然,你還可以在輸入英文的句號之后,按下tab,對方法、屬性的名稱進行補全:
In [3]: b = [1, 2, 3] In [4]: b.<Tab> b.append b.count b.insert b.reverse b.clear b.extend b.pop b.sort b.copy b.index b.remove
模塊也可以通過相同的方式補全:
In [1]: import datetime In [2]: datetime.<Tab> datetime.date datetime.MAXYEAR datetime.timedelta datetime.datetime datetime.MINYEAR datetime.timezone datetime.datetime_CAPI datetime.time datetime.tzinfo
在Jupyter notebook和新版的IPython(5.0及以上)中,自動補全是在下拉選項中展現,而不是文本輸出。
請注意IPython默認情況下隱藏了以下劃線開始的方法和屬性,諸如魔術方法、內部“私有”方法和屬性,以避免雜亂的顯示(使新手混淆)。這些你當然也是可以使用tab補全的,但是必須先輸入下劃線才能看到它們。如果你總是想在tab補全時直接看到它們,則需要修改IPython配置。參見IPython官方文檔可以找到相關內容。
tab補全除了在搜索交互命名空間和補全對象或模塊屬性時有用,在很多其他上下文場景中也有用。當輸入任意路徑(甚至是Python字符串)時,按下Tab鍵將補全你的計算機文件系統中匹配你輸入內容的值:
In [7]: datasets/movielens/<Tab> datasets/movielens/movies.dat datasets/movielens/README datasets/movielens/ratings.dat datasets/movielens/users.dat In [7]: path = 'datasets/movielens/<Tab> datasets/movielens/movies.dat datasets/movielens/README datasets/movielens/ratings.dat datasets/movielens/users.dat
與%run命令搭配使用(參見2.2.5節),該功能將為你節省大量鍵盤輸入。
tab補全的另一個應用場景是在函數的關鍵字參數(包含=號)中節約時間,見圖2-4。

圖2-4:在Jupyter notebook中自動補全函數關鍵字參數
本節之后將更進一步介紹函數。
2.2.4 內省
在一個變量名的前后使用問號(?)可以顯示一些關于該對象的概要信息:
In [8]: b = [1, 2, 3] In [9]: b? Type: list String Form:[1, 2, 3] Length: 3 Docstring: list() -> new empty list list(iterable) -> new list initialized from iterable's items In [10]: print? Docstring: print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False) Prints the values to a stream, or to sys.stdout by default. Optional keyword arguments: file: a file-like object (stream); defaults to the current sys.stdout. sep: string inserted between values, default a space. end: string appended after the last value, default a newline. flush: whether to forcibly flush the stream. Type: builtin_function_or_method
這就是對象內省。如果對象是一個函數或實例方法且文檔字符串已經寫好,則文檔字符串會顯示出來。假設已經寫好如下函數(你可以在IPython或Jupyter中復現):
def add_numbers(a, b): """ Add two numbers together Returns ------- the_sum : type of arguments """ return a + b
然后使用?來顯示文檔字符串:
In [11]: add_numbers? Signature: add_numbers(a, b) Docstring: Add two numbers together Returns ------- the_sum : type of arguments File: <ipython-input-9-6a548a216e27> Type: function
使用雙問號??可以顯示函數的源代碼:
In [12]: add_numbers? ? Signature: add_numbers(a, b) Source: def add_numbers(a, b): """ Add two numbers together Returns ------- the_sum : type of arguments """ return a + b File: <ipython-input-9-6a548a216e27> Type: function
?有一個終極用途,可以像標準Unix或Windows命令行一樣搜索IPython命名空間。把一些字符和通配符(星號*)結合在一起,會顯示所有匹配通配符表達式的命名。例如,我們可以得到NumPy頂層函數中包含load的函數名列表:
In [13]: np.*load*? np.__loader__ np.load np.loads np.loadtxt np.pkgload
2.2.5 %run命令
可以在IPython會話中使用%run命令運行任意的Python程序文件。假設你已經在ipython_script_test.py中寫好了如下的簡單腳本:
def f(x, y, z): return (x + y) / z a = 5 b = 6 c = 7.5 result = f(a, b, c)
可以將文件名作為參數傳給%run命令:
In [14]: %run ipython_script_test.py
腳本是在空白命名空間(沒有導入模塊或其他定義變量)中運行的,因此這個行為與在命令行中使用python script.py來運行程序是相同的。文件中定義的所有變量(導入的、函數中的、全局定義的)在運行后,可以在IPython命令行中使用(除非出現某種異常):
In [15]: c Out [15]: 7.5 In [16]: result Out[16]: 1.4666666666666666
如果一個Python腳本需要命令行提供參數(通過sys.argv獲得),那么則需要在命令行的文件路徑后面加上參數進行傳遞:
如果你想讓待運行的腳本使用交互式IPython命名空間中已有的變量,請使用%run -i替代普通的%run命令。
在Jupyter notebook中,如果你想將腳本導入一個代碼單元,可以使用%load魔術函數:
>>> %load ipython_script_test.py def f(x, y, z): return (x + y) / z a = 5 b = 6 c = 7.5 result = f(a, b, c)
2.2.5.1 中斷運行中的代碼
在任意代碼運行時按下Ctrl-C,無論腳本是通過%run或是其他長命令運行的,都將引起KeyboardInterrupt。除了某些特殊情況,這將導致所有的Python程序立即停止運行。
當一段Python代碼被其他已經編譯的擴展模塊調用時,按下Ctrl-C并不會讓程序立即停止運行。在這些情況下,你需要等到控制流重新返回Python解釋器,在更糟糕的情況下可能要強制結束Python進程。
2.2.6 執行剪貼板中的程序
如果你正在使用Jupyter notebook,你可以將代碼復制粘貼到代碼單元,然后運行。在IPython中可以直接運行剪貼板中的程序。假設你在其他的應用中寫了如下代碼:
x = 5 y = 7 if x > 5: x += 1 y = 8
使用以上代碼,最簡單的方法就是%paste和%cpaste魔術函數。%paste會獲得剪貼板中的所有文本,并在命令行中作為一個代碼塊去執行:
In [17]: %paste x = 5 y = 7 if x > 5: x += 1 y = 8
## -- 傳入文本的結尾 --
%cpaste與之類似,只不過它會給出一個特殊的提示符,讓你粘貼代碼:
In [18]: %cpaste Pasting code; enter '--' alone on the line to stop or use Ctrl-D. :x = 5 :y = 7 :if x > 5: : x += 1 : y = 8 :--
:
使用%cpaste,你可以自由地在執行代碼前盡可能多地粘貼代碼。你也許會想著使用%cpaste在執行前看下粘貼的代碼,如果你發現粘貼的代碼有誤,可以按下Ctrl-C來中斷%cpaste提示符。
2.2.7 終端快捷鍵
IPython有很多用于瀏覽提示、查看歷史命令的快捷鍵(Emacs文本編輯器和Unix bash命令行的使用者會很熟悉)。表2-1總結了最常用的快捷鍵。圖2-5展示了部分快捷功能,比如光標移動。

圖2-5:IPython命令行的部分快捷鍵
表2-1:標準IPython快捷鍵

需要注意的是,Jupyter notebook有一個獨立的快捷鍵集合用于導航和編輯。由于Jupyter notebook的快捷鍵更新比IPython更為頻繁,建議你使用Jupyter notebook集成在菜單欄中的幫助系統。
2.2.8 關于魔術命令
IPython的特殊命令(沒有內建到Python自身中去)被稱為“魔術”命令。這些命令被設計用于簡化常見任務,確保用戶更容易控制IPython系統的行為。魔術命令的前綴符號是百分號%。例如,你可以使用%timeit來檢查一段Python語句的執行時間,比如一個矩陣操作(后續將會詳細討論%timeit):
In [20]: a = np.random.randn(100, 100) In [20]: %timeit np.dot(a, a) 10000 loops, best of 3: 20.9 μs per loop
魔術命令可以看作是IPython系統內部的命令行程序。大多數魔術命令都可以使用?查看額外的“命令行”選項:
In [21]: %debug? Docstring: :: %debug [--breakpoint FILE:LINE] [statement [statement ...]] Activate the interactive debugger. This magic command support two ways of activating debugger. One is to activate debugger before executing code. This way, you can set a break point, to step through the code from the point. You can use this mode by giving statements to execute and optionally a breakpoint. The other one is to activate debugger in post-mortem mode. You can activate this mode simply running %debug without any argument. If an exception has just occurred, this lets you inspect its stack frames interactively. Note that this will always work only on the last traceback that occurred, so you must call this quickly after an exception that you wish to inspect has fired, because if another one occurs, it clobbers the previous one. If you want IPython to automatically do this on every exception, see the %pdb magic for more details. positional arguments: statement Code to run in debugger. You can omit this in cell magic mode. optional arguments: --breakpoint <FILE:LINE>, -b <FILE:LINE> Set break point at LINE in FILE.
魔術函數也可以不加百分號%就使用,只要沒有變量被定義為與魔術函數相同的名字即可。這種特性被稱為自動魔術,通過%automagic進行啟用/禁用關。
一些魔術函數也像Python函數一樣,其輸出可以賦給一個變量:
In [22]: %pwd Out[22]: '/home/wesm/code/pydata-book In [23]: foo = %pwd In [24]: foo Out[24]: '/home/wesm/code/pydata-book'
由于IPython的文檔可以在系統內訪問,建議使用%quickref或者%magic探索所有的特殊命令。表2-2是在IPython中高效進行交互式計算和Python開發所常用的重要命令。
表2-2:IPython常用魔術命令

2.2.9 matplotlib集成
IPython能在分析計算領域流行的原因之一,就是它和數據可視化、用戶界面庫(如matplotlib)的良好集成。即使你從未使用過matplotlib也不必擔心,本書的后續章節會詳細討論該部分內容。%matplotlib魔術函數可以設置matplotlib與IPython命令行或Jupyter notebook的集成。這個命令很重要,否則你創建的圖可能不會出現(notebook),或者直到結束也無法控制會話(命令行)。
在IPython命令行中,運行%matplotlib命令可以生成多個繪圖窗口,而無須干擾控制臺的會話。
In [26]: %matplotlib Using matplotlib backend: Qt4Agg
在Jupyter中,命令會有些許不同(見圖2-6):
In [26]: %matplotlib inline

圖2-6:Jupyter內聯matplotlib繪圖