1. 程式人生 > >《利用Python進行資料分析》學習筆記ch03(4)

《利用Python進行資料分析》學習筆記ch03(4)

這章主要是介紹IPython,但因為我現在一直在用Jupyter,所以結果有些出入,看後續的章節是否還有一些較大的問題,這裡就先將就一下。

1.IPython基礎

import numpy as np
from numpy.random import randn
data = {i:randn() for i in range(7)}
data
{0: 0.8611346383812991,
 1: 0.5362350286600601,
 2: -0.307231562803592,
 3: -0.4950796767150949,
 4: -0.15818185039404367,
 5: 1.2129329945075356,
 6: -0.14162732613012588}
from numpy.random import randn
data = {i:randn() for i in range(7)}
print(data)
{0: 2.415889425442822, 1: -0.5219924948118143, 2: 0.6772666078389369, 3: 0.25290209089906857, 4: -1.0438101366342571, 5: 0.6095941975610393, 6: 0.5779498654429005}

1.2Tab鍵自動完成

按下Tab鍵,當前名稱空間中任何與已輸入的字串相匹配的變數(物件、函式等)就會被找出來

an_apple = 27
an_example = 42

an 之後會顯示an_apple and an_example any
也可以在任何物件後面輸入一個句點以便自動完成方法和屬性的輸入

b=[1,2,3]

b. 之後顯示b.append b.extend等
還可以應用在模組上

import datetime

datetime. 之後顯示datetime.MAXYEAR等

Tab鍵自動完成功能不知可以用於搜尋名稱空間和自動完成物件或模組屬性。當輸入任何看上去像是檔案路勁的東西時(即使是在一個Python字串中),按下Tab鍵即可找出電腦檔案系統中與之匹配的東西:
Tab鍵自動完成功能還可用於函式關鍵字引數。

書上是mac系統,我用的是win系統,在檔案路徑上有所區別(這在上一章的路徑(path)輸入上就有所體現了),但是嘗試好幾次Tab還是沒有出現自動路徑選擇。

1.3內省

在變數的前面或後面加上一個問號(?)就可以將有關該物件的一些通用資訊顯示出來:

b?

Type: list
String form: [1, 2, 3]
Length: 3
Docstring:
list() -> new empty list
list(iterable) -> new list initialized from iterable’s items
這就叫做物件內省(object introspection)

如果該物件是一個函式或例項方法,則其docstring(如果有的話)也會被顯示出來

def add_numbers(a,b):
    """Add two numbers together

    returns
    - - - - - 
    the sum:type of arguments    
    """
    return a+b
add_numbers?

Signature: add_numbers(a, b)
Docstring:
Add two numbers together

returns

the sum:type of arguments
File: c:\users\administrator\documents\
Type: function

使用??還將顯示出該函式的原始碼(如果可能的話):

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: c:\users\administrator\documents\
Type: function

?還有一個用法,用搜索IPython名稱空間。一些字元配以萬用字元(*)即可顯示出所有與該萬用字元表示式相匹配的名稱

np.*load*?

np.loader
np.load
np.loads
np.loadtxt
np.pkgload

1.4%run命令

在IPython會話環境中,所有檔案都可以通過%run命令當做Python程式來執行。
假設在ipython_script_test.py中存放了一段簡單的指令碼,
只要將檔名傳給%run就可以運行了:
%run ipython_script_test.py

1.5執行剪貼簿中的程式碼

這一部分就不再贅述,複製貼上的問題以前就出現過了,使用IPython時,因為是逐行編譯所以不能大段的複製貼上,這裡就介紹了%paste和%cpaste這兩個魔術函式,因為我現在使用的是Jupyter所以就不在用IPython實踐了。
本書後面會介紹Jupyter,它使我們能以一種基於瀏覽器的notebook格式逐段對可執行程式碼單元進行分析。
目前我一直是使用Jupyter,確實很方便,日後看工作需要,如果需要IPyhon這樣的工具,才嘗試使用%paste和%cpaste這兩個魔術函式。

1.6鍵盤快捷鍵

不再贅述,因為目前就我掌握的一些快捷鍵已經夠用。

1.7異常和跟蹤

IPython預設會輸出整個呼叫棧跟蹤(traceback),其中還會附上呼叫棧各點附近的幾行程式碼作為上下參考
這裡就是說了IPython直譯器在對於顯示異常上會出現比較詳細的內容,這也是便於找出並排除異常。

1.8魔術命令

IPython有一些特殊命令(被稱為魔術命令(Magic Command)),他們有的為常見任務提供便利,有的則能使你能夠輕鬆控制IPython系統的行為,魔術命令是以百分號%為字首的命令。

魔術命令可以看作運行於IPython系統中的命令列程式。它們大都還有一些“命令列選項”,使用?即可檢視其選項

%reset?

Docstring:
Resets the namespace by removing all names defined by the user, if
called without arguments, or by removing some types of objects, such
as everything currently in IPython’s In[] and Out[] containers (see
the parameters for details).
Parameters
-f : force reset without asking for confirmation.

-s : ‘Soft’ reset: Only clears your namespace, leaving history intact.
References to objects may be kept. By default (without this option),
we do a ‘hard’ reset, giving you a new session and removing all
references to objects from the current session.

in : reset input history

out : reset output history

dhist : reset directory history

array : reset only variables that are NumPy arrays
See Also
reset_selective : invoked as %reset_selective
Examples
::

In [6]: a = 1

In [7]: a
Out[7]: 1

In [8]: ‘a’ in _ip.user_ns
Out[8]: True

In [9]: %reset -f

In [1]: ‘a’ in _ip.user_ns
Out[1]: False

In [2]: %reset -f in
Flushing input history

In [3]: %reset -f dhist in
Flushing directory history
Flushing input history
Notes
Calling this magic from clients that do not implement standard input,
such as the ipython notebook interface, will reset the namespace
without confirmation.
File: c:\anaconda3\lib\site-packages\ipython\core\magics\namespace.py

輸入%quickref或%magic即可檢視所有這些特殊命令

%magic

太長了,就不顯示了,當然也不是很懂。

1.9基於Qt的富GUI控制檯

IPython團隊開發了一個基於Qt框架,按照書上嘗試多次都沒有成功。

1.10matplotlib整合與pylab模式

之前也用這個建立過圖形了,這裡不再贅述,詳細的後面章節會講。

1.11使用命令歷史

1.12搜尋並重用歷史

就是按上箭頭,出現前幾個用過的語法,在IPython有效,在Jupyter並沒有成功。

1.13輸入和輸出變數

IPython會將輸入和輸出的引用儲存在一些特殊變數中。

2**27
134217728
_
134217728

輸入的文字被儲存在名為_ix的變數中,其中x是輸入的行號。每個輸入變數都有一個對應的輸出變數_x。

foo='bar'
foo
'bar'
_i16
"foo='bar'"
_17
'bar'

有幾個魔術命令可用於控制輸入和輸出歷史。
%hist列印全部和部分輸入歷史,可以選擇是否帶行號;
%reset用於清空interactive名稱空間,並可選擇是否清空輸入和輸出快取;
%xdel用於從IPython系統中一處特點物件的一切引用。

1.14記錄輸入和輸出

IPython能夠記錄整個控制檯會話,包括輸入和輸出,執行%logstart即可開始記錄日誌。

1.15與作業系統互動

IPython的另一個特點就是它跟作業系統shell結合得非常緊密,也就是說,你可以直接在IPyhton中實現標準的Windows或UNIX命令列活動。

1.16sehll命令和別名

在IPython中,以感嘆號(!)開頭的命令列表示其後的所有內容需要在系統shell中執行,可以刪除檔案、修改目錄或執行任意其他處理過程。

1.17目錄書籤系統

IPython有一個簡單的目錄書籤系統,它儲存常用目錄的別名以實現快速跳轉

%bookmark db /home/wesm/Dropbox
cd db
(bookmark:db) -> /home/wesm/Dropbox
[WinError 3] 系統找不到指定的路徑。: '/home/wesm/Dropbox'
C:\Users\Administrator\Documents

2.軟體開發工具

IPython提供了一些簡單易用的程式碼執行時間及效能分析工具。

2.1互動式偵錯程式

除錯程式碼的最佳時機之一就是錯誤剛剛發生那會兒。%debug命令(在發生異常後馬上輸入)將會呼叫那個“事後”偵錯程式,並直接跳轉到引發異常的那個棧幀(stack frame)

%debug後總是卡死

當想要設定斷點或對函式/指令碼進行單步除錯以檢視各條語句的執行情況時,使用帶有-d選項的%run命令。之後立即輸入s(或step)才能進入指令碼。

使用IPython總是莫名卡住,但是使用IPthon就沒問題

除錯的其他使用場景

介紹了set_trace函式,看不懂

2.2測試程式碼的執行時間:%time和%timeit

測試一下各個部分或函式呼叫或語句的執行時間,瞭解哪些函式佔用的時間最多。

IPython專門提供了兩個魔術函式(%time和%timeit)以便自動完成該過程。

#一個非常大的字串陣列
strings = ['foo','foobar','baz','qux','python','Guido Van Rossum']*100000
method1 = [x for x in strings if x.startswith('foo')]
method2 = [x for x in strings if x[:3]=='foo']
%time method1 = [x for x in strings if x.startswith('foo')]
Wall time: 429 ms
%time method2 = [x for x in strings if x[:3]=='foo']
Wall time: 315 ms

如果對相同語句多次執行%time的話,就會發現其結果是會變的。為了得到更為精確的結果,需要使用魔術函式%timeit。對於任意語句,它會自動多次執行以產生一個非常精確的平均執行時間。

%timeit [x for x in strings if x.startswith('foo')]
1 loop, best of 3: 372 ms per loop
%timeit [x for x in strings if x[:3]=='foo']
1 loop, best of 3: 286 ms per loop
x='foobar'
y='foo'
%timeit x.startswith(y)
The slowest run took 8.09 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 746 ns per loop
%timeit x[:3]==y
The slowest run took 8.02 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 677 ns per loop

2.3基本效能分析:%prun和%run -p

程式碼的效能分析跟程式碼執行時間密切相關,只不過它關注的是耗費時間的位置。
主要的Python效能分析工具是cProfile模組,cProfile在執行一個程式或程式碼塊時,會記錄各函式所耗費的時間。

cProfile一般是在命令列上使用的,它將執行整個程式然後輸出各個函式的執行時間。

import numpy as np
from numpy.linalg import eigvals
def run_experiment(niter = 100):
    K = 100
    results = []
    for _ in xrange(niter):
        mat = np.random.randn(K,K)
        max_eigenvalue = np.abs(eigvals(mat)).max()
        results.append(max_eigenvalue)
    return results
some_results = run_experiment()
print ('Largest one we saw: %s' %np.max(some_results))
---------------------------------------------------------------------------

NameError                                 Traceback (most recent call last)

<ipython-input-74-a79a1debc6e1> in <module>()
----> 1 some_results = run_experiment()
      2 print ('Largest one we saw: %s' %np.max(some_results))


<ipython-input-71-2291e045be9f> in run_experiment(niter)
      4     K = 100
      5     results = []
----> 6     for _ in xrange(niter):
      7         mat = np.random.randn(K,K)
      8         max_eigenvalue = np.abs(eigvals(mat)).max()


NameError: name 'xrange' is not defined

總是報錯,問題好像出在xrange中。

2.4逐行分析函式效能

使用一個叫做line_profiler的小型庫,其中有一個新的魔術函式%lprun,它可以對一個或多個函式進行逐行效能分析。

通常用%prun(cProfile)做“巨集觀的”效能分析,而用%lprun(line_profiler)做“微觀的”效能分析。

這一塊也同樣總是報錯,我想這可能是版本的差異也可能是直譯器的原因。

3.IPython HTML Notebook

import matplotlib.pyplot as plt
%matplotlib inline
img = plt.imread('C:\\pytest\\ch03\\stinkbug.png')
plt.imshow(img)
<matplotlib.image.AxesImage at 0x266b1b53ac8>

這裡寫圖片描述

注意這裡與書上的區別。

4.利用IPython提高程式碼開發效率的幾點提示

4.1重新載入模組依賴項

使用reload函式就可以在每次執行py檔案時都使用最新版的檔案。
在執行之前加一句語法。
import some_lib
reload(some_lib)

4.2程式碼設計提示

實踐出真知

保留有意義的物件和資料

扁平結構要比巢狀結構好

無懼大檔案