# 1.1 科學計算工具及流程
> 作者 : Fernando Perez, Emmanuelle Gouillart, Ga?l Varoquaux, Valentin Haenel
## 1.1.1 為什么是Python?
### 1.1.1.1 科學家的需求
* 獲得數據(模擬,實驗控制)
* 操作及處理數據
* 可視化結果... 理解我們在做什么!
* 溝通結果:生成報告或出版物的圖片,寫報告
### 1.1.1.2 要求
* 對于經典的數學方法及基本的方法,有豐富的現成工具:我們不希望重新編寫程序去畫出曲線、傅立葉變換或者擬合算法。不要重復發明輪子!
* 易于學習:計算機科學不是我們的工作也不是我們的教育背景。我們想要在幾分鐘內畫出曲線,平滑一個信號或者做傅立葉變換,
* 可以方便的與合作者、學生、客戶進行交流,代碼可以存在于實驗室或公司里面:代碼的可讀性應該像書一樣。因此,這種語言應該包含盡可能少的語法符號或者不必要的常規規定,使來自數學或科學領域讀者愉悅的理解這些代碼。
* 語言高效,執行快...但是不需要是非常快的代碼,因為如果我們花費了太多的時間來寫代碼,非常快的代碼也是無用的。
* 一個單一的語言/環境做所有事,如果可能的話,避免每個新問題都要學習新軟件
### 1.1.1.3 現有的解決方案
科學家用哪種解決方案進行工作?
### 編譯語言:C、C++、Fortran等。
* 優勢:
* 非常快。極度優化的編譯器。對于大量的計算來說,很難比這些語言的性能更好。
* 一些非常優化的科學計算包。比如:BLAS(向量/矩陣操作)
* 不足:
* 使用起來令人痛苦:開發過程中沒有任何互動,強制編譯步驟,啰嗦的語法(&, ::, }}, ; 等),手動內存管理(在C中非常棘手)。對于非計算機學家他們是**艱深的語言**。
### 腳本語言:Matlab
* 優勢:
* 對不同的領域的多種算法都有非常的類庫。執行很快,因為這些類庫通常使用編譯語言寫的。
* 友好的開發環境:完善的、組織良好的幫助,整合的編輯器等
* 有商業支持
* 不足:
* 基礎語言非常欠缺,會限制高級用戶
* 不是免費的
### 其他腳本語言:Scilab、Octave、Igor、R、IDL等。
* 優勢:
* 開源、免費,或者至少比Matlba便宜。
* 一些功能非常高級(R的統計,Igor的圖形等。)
* 不足:
* 比Matlab更少的可用算法,語言也并不更高級
* 一些軟件更專注于一個領域。比如,Gnuplot或xmgrace畫曲線。這些程序非常強大,但是他們只限定于一個單一用途,比如作圖。
### 那Python呢?
* 優勢:
* 非常豐富的科學計算包(盡管比Matlab少一些)
* 精心設計的語言,允許寫出可讀性非常好并且結構良好的代碼:我們“按照我們所想去寫代碼”。
* 對于科學計算外的其他任務也有許多類庫(網站服務器管理,串口接收等等。)
* 免費的開源軟件,廣泛傳播,有一個充滿活力的社區。
* 不足:
* 不太友好的開發環境,比如與Matlab相比。(更加極客向)。
* 并不是在其他專業軟件或工具箱中可以找到算法都可以找到
## 1.1.2 Python科學計算的構成
與Matlba,Scilab或者R不同,Python并沒有預先綁定的一組科學計算模塊。下面是可以組合起來獲得科學計算環境的基礎的組件。
* **Python**,通用的現代計算語言
* Python語言:數據類型(字符string,整型int),流程控制,數據集合(列表list,字典dict),模式等等。
* 標準庫及模塊
* 用Pyhon寫的大量專業模塊及應用:網絡協議、網站框架等...以及科學計算。
* 開發工具(自動測試,文檔生成)
* **IPython**, 高級的**Python Shell** [http://ipython.org/](http://ipython.org/) 
* **Numpy** : 提供了強大數值數組對象以及程序去操作它們。[http://www.numpy.org/](http://www.numpy.org/)
* **Scipy** : 高級的數據處理程序。優化、回歸插值等[http://www.scipy.org/](http://www.scipy.org/)
* **Matplotlib** : 2D可視化,“出版級”的圖表[http://matplotlib.sourceforge.net/](http://matplotlib.sourceforge.net/) 
* **Mayavi** : 3D可視化[http://code.enthought.com/projects/mayavi/](http://code.enthought.com/projects/mayavi/) 
## 1.1.3 交互工作流:IPython和文本編輯器
**測試和理解算法的交互工作**:在這個部分我們描述一下用[IPython](http://ipython.org/)的交互工作流來方便的研究和理解算法。
Python是一門通用語言。與其他的通用語言一樣,沒有一個絕對權威的工作環境,也不止一種方法使用它。盡管這對新人來說不太好找到適合自己的方式,但是,這使得Python被用于在網站服務器或嵌入設備中編寫程序。
> **本部分的參考文檔**:
>
> **IPython用戶手冊**:[http://ipython.org/ipython-doc/dev/index.html](http://ipython.org/ipython-doc/dev/index.html)
### 1.1.3.1 命令行交互
啟動ipython:
In?[1]:
```
print('Hello world')
```
```
Hello world
```
在對象后使用?運算符獲得幫助:
```
In [2]: print
Type: builtin_function_or_method
Base Class: <type ’builtin_function_or_method’>
String Form: <built-in function print>
Namespace: Python builtin
Docstring:
print(value, ..., sep=’ ’, end=’\n’, file=sys.stdout)
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.
```
### 1.1.3.2 在編輯器中詳盡描述算法
在文本編輯器中,創建一個my_file.py文件。在EPD([Enthought Python Distribution](https://www.enthought.com/products/epd/))中,你可以從開始按鈕使用_Scite_。在[Python(x,y)](https://code.google.com/p/pythonxy/)中, 你可以使用Spyder。在Ubuntu中, 如果你還沒有最喜歡的編輯器,我們建議你安裝[Stani’s Python editor](http://sourceforge.net/projects/spe/)。在這個文件中,輸入如下行:
```
s = 'Hello world'
print(s)
```
現在,你可以在IPython中運行它,并研究產生的變量:
In?[2]:
```
%run my_file.py
```
```
Hello world
```
In?[3]:
```
s
```
Out[3]:
```
'Hello world'
```
In?[4]:
```
%whos
```
```
Variable Type Data/Info
----------------------------
s str Hello world
```
> **從腳本到函數**
>
> 盡管僅使用腳本工作很誘人,即一個滿是一個接一個命令的文件,但是要有計劃的逐漸從腳本進化到一組函數:
>
> * 腳本不可復用,函數可復用。
>
>
> * 以函數的角度思考,有助于將問題拆分為小代碼塊。
### 1.1.3.3 IPython提示與技巧
IPython用戶手冊包含關于使用IPython的大量信息,但是,為了幫你你更快的入門,這里快速介紹三個有用的功能:_歷史_,_魔法函數_,_別稱_和_tab完成_。
與Unix Shell相似,IPython支持命令歷史。按上下在之前輸入的命令間切換:
```
In [1]: x = 10
In [2]: <UP>
In [2]: x = 10
```
IPython通過在命令前加_%_字符的前綴,支持所謂魔法函數。例如,前面部分的函數_run_和_whos_都是魔法函數。請注意_automagic_設置默認是啟用,允許你忽略前面的_%_。因此,你可以只輸入魔法函數仍然是有效的。
其他有用的魔法函數:
* **%cd** 改變當前目錄
In?[6]:
```
cd ..
```
```
/Users/cloga/Documents
```
* **%timeit** 允許你使用來自標準庫中的timeit模塊來記錄執行短代碼端的運行時間
In?[7]:
```
timeit x = 10
```
```
10000000 loops, best of 3: 26.7 ns per loop
```
* **%cpaste** 允許你粘貼代碼,特別是來自網站的代碼,前面帶有標準的Python提示符 (即 >>>) 或ipython提示符的代碼(即 in [3]):
```
In [5]: cpaste
Pasting code; enter ’--’ alone on the line to stop or use Ctrl-D. :In [3]: timeit x = 10
:--
10000000 loops, best of 3: 85.9 ns per loop
In [6]: cpaste
Pasting code; enter ’--’ alone on the line to stop or use Ctrl-D. :>>> timeit x = 10
:--
10000000 loops, best of 3: 86 ns per loop
```
* **%debug** 允許你進入事后除錯。也就是說,如果你想要運行的代碼拋出了一個異常,使用**%debug**將在拋出異常的位置進入排錯程序。
```
In [7]: x === 10
File "<ipython-input-6-12fd421b5f28>", line 1
x === 10 ^
SyntaxError: invalid syntax
In [8]: debug
> /home/esc/anaconda/lib/python2.7/site-packages/IPython/core/compilerop.py(87)ast_parse()
86 and are passed to the built-in compile function."""
---> 87 return compile(source, filename, symbol, self.flags | PyCF_ONLY_AST, 1)
88
ipdb>locals()
{’source’: u’x === 10\n’, ’symbol’: ’exec’, ’self’:
<IPython.core.compilerop.CachingCompiler instance at 0x2ad8ef0>,
’filename’: ’<ipython-input-6-12fd421b5f28>’}
```
> **IPython help**
>
> * 內置的IPython手冊可以通過_%quickref_魔法函數進入。
> * 輸入_%magic_會顯示所有可用魔法函數的列表。
而且IPython提供了大量的_別稱_來模擬常見的UNIX命令行工具比如_ls_等于list files,_cp_等于copy files以及_rm_等于remove files。輸入_alias_可以顯示所有的別稱的列表:
In?[5]:
```
alias
```
```
Total number of aliases: 12
```
Out[5]:
```
[('cat', 'cat'),
('cp', 'cp'),
('ldir', 'ls -F -G -l %l | grep /$'),
('lf', 'ls -F -l -G %l | grep ^-'),
('lk', 'ls -F -l -G %l | grep ^l'),
('ll', 'ls -F -l -G'),
('ls', 'ls -F -G'),
('lx', 'ls -F -l -G %l | grep ^-..x'),
('mkdir', 'mkdir'),
('mv', 'mv'),
('rm', 'rm'),
('rmdir', 'rmdir')]
```
最后,提一下_tab完成_功能,我們從IPython手冊引用它的描述:
> Tab completion, especially for attributes, is a convenient way to explore the structure of any object you’re dealing with. Simply type object_name. <tab>to view the object’s attributes. Besides Python objects and keywords, tab completion also works on file and directory names.</tab>
```
In [1]: x = 10
In [2]: x.<TAB>
x.bit_length x.conjugate x.denominator x.imag x.numerator x.real
In [3]: x.real.
x.real.bit_length x.real.denominator x.real.numerator x.real.conjugate x.real.imag x.real.real
In [4]: x.real.
```
- 介紹
- 1.1 科學計算工具及流程
- 1.2 Python語言
- 1.3 NumPy:創建和操作數值數據
- 1.4 Matplotlib:繪圖
- 1.5 Scipy:高級科學計算
- 1.6 獲取幫助及尋找文檔
- 2.1 Python高級功能(Constructs)
- 2.2 高級Numpy
- 2.3 代碼除錯
- 2.4 代碼優化
- 2.5 SciPy中稀疏矩陣
- 2.6 使用Numpy和Scipy進行圖像操作及處理
- 2.7 數學優化:找到函數的最優解
- 2.8 與C進行交互
- 3.1 Python中的統計學
- 3.2 Sympy:Python中的符號數學
- 3.3 Scikit-image:圖像處理
- 3.4 Traits:創建交互對話
- 3.5 使用Mayavi進行3D作圖
- 3.6 scikit-learn:Python中的機器學習