├── .gitignore ├── 1.1科学计算工具及流程.ipynb ├── 1.2Python语言.ipynb ├── 1.3NumPy:创建和操作数值数据.ipynb ├── 1.4Matplotlib:绘图.ipynb ├── 1.5Scipy:高级科学计算.ipynb ├── 1.6. 获取帮助及寻找文档.ipynb ├── 2.1. Python高级功能(Constructs).ipynb ├── 2.2. 高级Numpy.ipynb ├── 2.3. 代码除错.ipynb ├── 2.4. 代码优化.ipynb ├── 2.5. SciPy中稀疏矩阵.ipynb ├── 2.6. 使用Numpy和Scipy进行图像操作及处理.ipynb ├── 2.7. 数学优化:找到函数的最优解.ipynb ├── 2.8. 与C进行交互.ipynb ├── 3.1 Python中的统计学.ipynb ├── 3.2. Sympy:Python中的符号数学.ipynb ├── 3.3. Scikit-image:图像处理.ipynb ├── 3.4. Traits:创建交互对话.ipynb ├── 3.5. 使用Mayavi进行3D作图.ipynb ├── 3.6. scikit-learn:Python中的机器学习.ipynb ├── README.md ├── data ├── LICENCE.txt ├── MV_HFV_012.jpg ├── elephant.png ├── max-speeds.npy ├── moonlanding.png ├── organisms.txt ├── populations.txt ├── species.txt ├── test.png ├── test.wav ├── test2.png ├── waveform_1.npy ├── waveform_2.npy └── women_percentage.txt ├── demo.py ├── demo.pyc ├── demo_opt.py ├── demo_opt.pyc ├── etc └── fstab ├── examples ├── brain_size.csv └── iris.csv ├── face.png ├── face.raw ├── file.mat ├── foo.txt ├── ica.py ├── ica.pyc ├── index_error.py ├── local_logo.png ├── mandelbrot.png ├── plot.png ├── pop.npy ├── pop2.txt ├── red_elephant.png ├── tiny_elephant.png ├── untitled.txt ├── wages.txt └── wiener_filtering.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *,cover 47 | .hypothesis/ 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | local_settings.py 56 | 57 | # Flask stuff: 58 | instance/ 59 | .webassets-cache 60 | 61 | # Scrapy stuff: 62 | .scrapy 63 | 64 | # Sphinx documentation 65 | docs/_build/ 66 | 67 | # PyBuilder 68 | target/ 69 | 70 | # Jupyter Notebook 71 | .ipynb_checkpoints 72 | 73 | # pyenv 74 | .python-version 75 | 76 | # celery beat schedule file 77 | celerybeat-schedule 78 | 79 | # dotenv 80 | .env 81 | 82 | # virtualenv 83 | .venv/ 84 | venv/ 85 | ENV/ 86 | 87 | # Spyder project settings 88 | .spyderproject 89 | 90 | # Rope project settings 91 | .ropeproject 92 | 93 | # macOS ignore files 94 | *.DS_Store 95 | .AppleDouble 96 | .LSOverride 97 | 98 | # Icon must end with two \r 99 | Icon 100 | 101 | 102 | # Thumbnails 103 | ._* 104 | 105 | # Files that might appear in the root of a volume 106 | .DocumentRevisions-V100 107 | .fseventsd 108 | .Spotlight-V100 109 | .TemporaryItems 110 | .Trashes 111 | .VolumeIcon.icns 112 | .com.apple.timemachine.donotpresent 113 | 114 | # Directories potentially created on remote AFP share 115 | .AppleDB 116 | .AppleDesktop 117 | Network Trash Folder 118 | Temporary Items 119 | .apdisk 120 | -------------------------------------------------------------------------------- /1.1科学计算工具及流程.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | ">作者 : Fernando Perez, Emmanuelle Gouillart, Gaël Varoquaux, Valentin Haenel\n", 8 | "\n", 9 | "# 1.1 为什么是Python?\n", 10 | "\n", 11 | "## 1.1.1 科学家的需求\n", 12 | "\n", 13 | "- 获得数据(模拟,实验控制)\n", 14 | "- 操作及处理数据\n", 15 | "- 可视化结果... 理解我们在做什么!\n", 16 | "- 沟通结果:生成报告或出版物的图片,写报告\n", 17 | "\n", 18 | "## 1.1.2 要求\n", 19 | "\n", 20 | "- 对于经典的数学方法及基本的方法,有丰富的现成工具:我们不希望重新编写程序去画出曲线、傅立叶变换或者拟合算法。不要重复发明轮子!\n", 21 | "- 易于学习:计算机科学不是我们的工作也不是我们的教育背景。我们想要在几分钟内画出曲线,平滑一个信号或者做傅立叶变换,\n", 22 | "- 可以方便的与合作者、学生、客户进行交流,代码可以存在于实验室或公司里面:代码的可读性应该像书一样。因此,这种语言应该包含尽可能少的语法符号或者不必要的常规规定,使来自数学或科学领域读者愉悦的理解这些代码。\n", 23 | "- 语言高效,执行快...但是不需要是非常快的代码,因为如果我们花费了太多的时间来写代码,非常快的代码也是无用的。\n", 24 | "- 一个单一的语言/环境做所有事,如果可能的话,避免每个新问题都要学习新软件\n", 25 | "\n", 26 | "## 1.1.3 现有的解决方案\n", 27 | "\n", 28 | "科学家用哪种解决方案进行工作?\n", 29 | "\n", 30 | "### 编译语言:C、C++、Fortran等。\n", 31 | "\n", 32 | "- 优势:\n", 33 | " - 非常快。极度优化的编译器。对于大量的计算来说,很难比这些语言的性能更好。\n", 34 | " - 一些非常优化的科学计算包。比如:BLAS(向量/矩阵操作)\n", 35 | "\n", 36 | "- 不足:\n", 37 | " - 使用起来令人痛苦:开发过程中没有任何互动,强制编译步骤,啰嗦的语法(&, ::, }}, ; 等),手动内存管理(在C中非常棘手)。对于非计算机学家他们是**艰深的语言**。\n", 38 | "\n", 39 | "### 脚本语言:Matlab\n", 40 | "- 优势:\n", 41 | " - 对不同的领域的多种算法都有非常的类库。执行很快,因为这些类库通常使用编译语言写的。\n", 42 | " - 友好的开发环境:完善的、组织良好的帮助,整合的编辑器等\n", 43 | " - 有商业支持\n", 44 | "\n", 45 | "- 不足:\n", 46 | " - 基础语言非常欠缺,会限制高级用户\n", 47 | " - 不是免费的\n", 48 | " \n", 49 | "### 其他脚本语言:Scilab、Octave、Igor、R、IDL等。\n", 50 | "\n", 51 | "- 优势:\n", 52 | " - 开源、免费,或者至少比Matlba便宜。\n", 53 | " - 一些功能非常高级(R的统计,Igor的图形等。)\n", 54 | "\n", 55 | "- 不足:\n", 56 | " - 比Matlab更少的可用算法,语言也并不更高级\n", 57 | " - 一些软件更专注于一个领域。比如,Gnuplot或xmgrace画曲线。这些程序非常强大,但是他们只限定于一个单一用途,比如作图。\n", 58 | "\n", 59 | "### 那Python呢?\n", 60 | "\n", 61 | "- 优势:\n", 62 | " - 非常丰富的科学计算包(尽管比Matlab少一些)\n", 63 | " - 精心设计的语言,允许写出可读性非常好并且结构良好的代码:我们“按照我们所想去写代码”。\n", 64 | " - 对于科学计算外的其他任务也有许多类库(网站服务器管理,串口接收等等。)\n", 65 | " - 免费的开源软件,广泛传播,有一个充满活力的社区。\n", 66 | "\n", 67 | "- 不足:\n", 68 | " - 不太友好的开发环境,比如与Matlab相比。(更加极客向)。\n", 69 | " - 并不是在其他专业软件或工具箱中可以找到算法都可以找到\n", 70 | "\n", 71 | "# 1.2 Python科学计算的构成\n", 72 | "\n", 73 | "与Matlba,Scilab或者R不同,Python并没有预先绑定的一组科学计算模块。下面是可以组合起来获得科学计算环境的基础的组件。\n", 74 | "\n", 75 | "- **Python**,通用的现代计算语言\n", 76 | " - Python语言:数据类型(字符string,整型int),流程控制,数据集合(列表list,字典dict),模式等等。\n", 77 | " - 标准库及模块\n", 78 | " - 用Pyhon写的大量专业模块及应用:网络协议、网站框架等...以及科学计算。\n", 79 | " - 开发工具(自动测试,文档生成)\n", 80 | "\n", 81 | "- **IPython**, 高级的**Python Shell** [http://ipython.org/](http://ipython.org/)\n", 82 | "![ipython](http://scipy-lectures.github.io/_images/snapshot_ipython.png)\n", 83 | "\n", 84 | "- **Numpy** : 提供了强大数值数组对象以及程序去操作它们。[http://www.numpy.org/](http://www.numpy.org/)\n", 85 | "- **Scipy** : 高级的数据处理程序。优化、回归插值等[http://www.scipy.org/](http://www.scipy.org/)\n", 86 | "- **Matplotlib** : 2D可视化,“出版级”的图表[http://matplotlib.sourceforge.net/](http://matplotlib.sourceforge.net/)\n", 87 | "![Matplotlib](http://scipy-lectures.github.io/_images/random_c.jpg)\n", 88 | "\n", 89 | "- **Mayavi** : 3D可视化[http://code.enthought.com/projects/mayavi/](http://code.enthought.com/projects/mayavi/)\n", 90 | "![Mayavi](http://scipy-lectures.github.io/_images/example_surface_from_irregular_data.jpg)\n", 91 | "\n", 92 | "# 1.3 交互工作流:IPython和文本编辑器\n", 93 | "\n", 94 | "** 测试和理解算法的交互工作**:在这个部分我们描述一下用[IPython](http://ipython.org/)的交互工作流来方便的研究和理解算法。\n", 95 | "\n", 96 | "Python是一门通用语言。与其他的通用语言一样,没有一个绝对权威的工作环境,也不止一种方法使用它。尽管这对新人来说不太好找到适合自己的方式,但是,这使得Python被用于在网站服务器或嵌入设备中编写程序。\n", 97 | "\n", 98 | "> **本部分的参考文档**:\n", 99 | "\n", 100 | "> **IPython用户手册**:[http://ipython.org/ipython-doc/dev/index.html](http://ipython.org/ipython-doc/dev/index.html)\n", 101 | "\n", 102 | "## 1.3.1 命令行交互\n", 103 | "\n", 104 | "启动ipython:" 105 | ] 106 | }, 107 | { 108 | "cell_type": "code", 109 | "execution_count": 1, 110 | "metadata": { 111 | "collapsed": false 112 | }, 113 | "outputs": [ 114 | { 115 | "name": "stdout", 116 | "output_type": "stream", 117 | "text": [ 118 | "Hello world\n" 119 | ] 120 | } 121 | ], 122 | "source": [ 123 | "print('Hello world')" 124 | ] 125 | }, 126 | { 127 | "cell_type": "markdown", 128 | "metadata": {}, 129 | "source": [ 130 | "在对象后使用?运算符获得帮助:\n", 131 | "```python\n", 132 | "In [2]: print\n", 133 | "Type: builtin_function_or_method\n", 134 | "Base Class: \n", 135 | "String Form: \n", 136 | "Namespace: Python builtin\n", 137 | "Docstring:\n", 138 | " print(value, ..., sep=’ ’, end=’\\n’, file=sys.stdout)\n", 139 | " Prints the values to a stream, or to sys.stdout by default.\n", 140 | " Optional keyword arguments:\n", 141 | " file: a file-like object (stream); defaults to the current sys.stdout.\n", 142 | " sep: string inserted between values, default a space.\n", 143 | " end: string appended after the last value, default a newline.\n", 144 | "```" 145 | ] 146 | }, 147 | { 148 | "cell_type": "markdown", 149 | "metadata": {}, 150 | "source": [ 151 | "## 1.3.2 在编辑器中详尽描述算法\n", 152 | "\n", 153 | "在文本编辑器中,创建一个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/)。在这个文件中,输入如下行:\n", 154 | "```python\n", 155 | "s = 'Hello world'\n", 156 | "print(s)\n", 157 | "```\n", 158 | "\n", 159 | "现在,你可以在IPython中运行它,并研究产生的变量:" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": 2, 165 | "metadata": { 166 | "collapsed": false 167 | }, 168 | "outputs": [ 169 | { 170 | "name": "stdout", 171 | "output_type": "stream", 172 | "text": [ 173 | "Hello world\n" 174 | ] 175 | } 176 | ], 177 | "source": [ 178 | "%run my_file.py" 179 | ] 180 | }, 181 | { 182 | "cell_type": "code", 183 | "execution_count": 3, 184 | "metadata": { 185 | "collapsed": false 186 | }, 187 | "outputs": [ 188 | { 189 | "data": { 190 | "text/plain": [ 191 | "'Hello world'" 192 | ] 193 | }, 194 | "execution_count": 3, 195 | "metadata": {}, 196 | "output_type": "execute_result" 197 | } 198 | ], 199 | "source": [ 200 | "s" 201 | ] 202 | }, 203 | { 204 | "cell_type": "code", 205 | "execution_count": 4, 206 | "metadata": { 207 | "collapsed": false 208 | }, 209 | "outputs": [ 210 | { 211 | "name": "stdout", 212 | "output_type": "stream", 213 | "text": [ 214 | "Variable Type Data/Info\n", 215 | "----------------------------\n", 216 | "s str Hello world\n" 217 | ] 218 | } 219 | ], 220 | "source": [ 221 | "%whos" 222 | ] 223 | }, 224 | { 225 | "cell_type": "markdown", 226 | "metadata": {}, 227 | "source": [ 228 | ">**从脚本到函数**\n", 229 | "\n", 230 | ">尽管仅使用脚本工作很诱人,即一个满是一个接一个命令的文件,但是要有计划的逐渐从脚本进化到一组函数:\n", 231 | "\n", 232 | ">- 脚本不可复用,函数可复用。\n", 233 | "\n", 234 | ">- 以函数的角度思考,有助于将问题拆分为小代码块。\n", 235 | "\n", 236 | "## 1.3.3 IPython提示与技巧\n", 237 | "\n", 238 | "IPython用户手册包含关于使用IPython的大量信息,但是,为了帮你你更快的入门,这里快速介绍三个有用的功能:*历史*,*魔法函数*,*别称*和*tab完成*。\n", 239 | "\n", 240 | "与Unix Shell相似,IPython支持命令历史。按上下在之前输入的命令间切换:\n", 241 | "```python\n", 242 | "In [1]: x = 10\n", 243 | "In [2]: \n", 244 | "In [2]: x = 10\n", 245 | "```\n", 246 | "\n", 247 | "IPython通过在命令前加*%*字符的前缀,支持所谓魔法函数。例如,前面部分的函数*run*和*whos*都是魔法函数。请注意*automagic*设置默认是启用,允许你忽略前面的*%*。因此,你可以只输入魔法函数仍然是有效的。\n", 248 | "\n", 249 | "其他有用的魔法函数:\n", 250 | "\n", 251 | "- **%cd** 改变当前目录" 252 | ] 253 | }, 254 | { 255 | "cell_type": "code", 256 | "execution_count": 6, 257 | "metadata": { 258 | "collapsed": false 259 | }, 260 | "outputs": [ 261 | { 262 | "name": "stdout", 263 | "output_type": "stream", 264 | "text": [ 265 | "/Users/cloga/Documents\n" 266 | ] 267 | } 268 | ], 269 | "source": [ 270 | "cd .." 271 | ] 272 | }, 273 | { 274 | "cell_type": "markdown", 275 | "metadata": {}, 276 | "source": [ 277 | "- **%timeit** 允许你使用来自标准库中的timeit模块来记录执行短代码端的运行时间" 278 | ] 279 | }, 280 | { 281 | "cell_type": "code", 282 | "execution_count": 7, 283 | "metadata": { 284 | "collapsed": false 285 | }, 286 | "outputs": [ 287 | { 288 | "name": "stdout", 289 | "output_type": "stream", 290 | "text": [ 291 | "10000000 loops, best of 3: 26.7 ns per loop\n" 292 | ] 293 | } 294 | ], 295 | "source": [ 296 | "timeit x = 10" 297 | ] 298 | }, 299 | { 300 | "cell_type": "markdown", 301 | "metadata": {}, 302 | "source": [ 303 | "- **%cpaste** 允许你粘贴代码,特别是来自网站的代码,前面带有标准的Python提示符 (即 >>>) 或ipython提示符的代码(即 in [3]):\n", 304 | "```python\n", 305 | "In [5]: cpaste\n", 306 | "Pasting code; enter ’--’ alone on the line to stop or use Ctrl-D. :In [3]: timeit x = 10\n", 307 | ":--\n", 308 | "10000000 loops, best of 3: 85.9 ns per loop\n", 309 | "In [6]: cpaste\n", 310 | "Pasting code; enter ’--’ alone on the line to stop or use Ctrl-D. :>>> timeit x = 10\n", 311 | ":--\n", 312 | "10000000 loops, best of 3: 86 ns per loop\n", 313 | "```\n", 314 | "- **%debug** 允许你进入事后除错。也就是说,如果你想要运行的代码抛出了一个异常,使用**%debug**将在抛出异常的位置进入排错程序。\n", 315 | "\n", 316 | "```python\n", 317 | "In [7]: x === 10\n", 318 | "File \"\", line 1\n", 319 | "x === 10 ^\n", 320 | " SyntaxError: invalid syntax\n", 321 | "In [8]: debug\n", 322 | "> /home/esc/anaconda/lib/python2.7/site-packages/IPython/core/compilerop.py(87)ast_parse()\n", 323 | " 86 and are passed to the built-in compile function.\"\"\"\n", 324 | " ---> 87 return compile(source, filename, symbol, self.flags | PyCF_ONLY_AST, 1)\n", 325 | "88\n", 326 | " ipdb>locals()\n", 327 | " {’source’: u’x === 10\\n’, ’symbol’: ’exec’, ’self’:\n", 328 | " ,\n", 329 | " ’filename’: ’’}\n", 330 | "```" 331 | ] 332 | }, 333 | { 334 | "cell_type": "markdown", 335 | "metadata": {}, 336 | "source": [ 337 | ">**IPython help**\n", 338 | "\n", 339 | ">- 内置的IPython手册可以通过*%quickref*魔法函数进入。\n", 340 | ">- 输入*%magic*会显示所有可用魔法函数的列表。\n", 341 | "\n", 342 | "而且IPython提供了大量的*别称*来模拟常见的UNIX命令行工具比如*ls*等于list files,*cp*等于copy files以及*rm*等于remove files。输入*alias*可以显示所有的别称的列表:" 343 | ] 344 | }, 345 | { 346 | "cell_type": "code", 347 | "execution_count": 5, 348 | "metadata": { 349 | "collapsed": false 350 | }, 351 | "outputs": [ 352 | { 353 | "name": "stdout", 354 | "output_type": "stream", 355 | "text": [ 356 | "Total number of aliases: 12\n" 357 | ] 358 | }, 359 | { 360 | "data": { 361 | "text/plain": [ 362 | "[('cat', 'cat'),\n", 363 | " ('cp', 'cp'),\n", 364 | " ('ldir', 'ls -F -G -l %l | grep /$'),\n", 365 | " ('lf', 'ls -F -l -G %l | grep ^-'),\n", 366 | " ('lk', 'ls -F -l -G %l | grep ^l'),\n", 367 | " ('ll', 'ls -F -l -G'),\n", 368 | " ('ls', 'ls -F -G'),\n", 369 | " ('lx', 'ls -F -l -G %l | grep ^-..x'),\n", 370 | " ('mkdir', 'mkdir'),\n", 371 | " ('mv', 'mv'),\n", 372 | " ('rm', 'rm'),\n", 373 | " ('rmdir', 'rmdir')]" 374 | ] 375 | }, 376 | "execution_count": 5, 377 | "metadata": {}, 378 | "output_type": "execute_result" 379 | } 380 | ], 381 | "source": [ 382 | "alias" 383 | ] 384 | }, 385 | { 386 | "cell_type": "markdown", 387 | "metadata": {}, 388 | "source": [ 389 | "最后,提一下*tab完成*功能,我们从IPython手册引用它的描述:\n", 390 | "\n", 391 | ">Tab completion, especially for attributes, is a convenient way to explore the structure of any object you’re dealing with. Simply type object_name. to view the object’s attributes. Besides Python objects and keywords, tab completion also works on file and directory names.\n", 392 | "\n", 393 | "```python\n", 394 | "In [1]: x = 10\n", 395 | "In [2]: x.\n", 396 | "x.bit_length x.conjugate x.denominator x.imag x.numerator x.real\n", 397 | "In [3]: x.real.\n", 398 | "x.real.bit_length x.real.denominator x.real.numerator x.real.conjugate x.real.imag x.real.real\n", 399 | "In [4]: x.real.\n", 400 | "```" 401 | ] 402 | } 403 | ], 404 | "metadata": { 405 | "kernelspec": { 406 | "display_name": "Python 2", 407 | "language": "python", 408 | "name": "python2" 409 | }, 410 | "language_info": { 411 | "codemirror_mode": { 412 | "name": "ipython", 413 | "version": 2 414 | }, 415 | "file_extension": ".py", 416 | "mimetype": "text/x-python", 417 | "name": "python", 418 | "nbconvert_exporter": "python", 419 | "pygments_lexer": "ipython2", 420 | "version": "2.7.10" 421 | } 422 | }, 423 | "nbformat": 4, 424 | "nbformat_minor": 0 425 | } 426 | -------------------------------------------------------------------------------- /1.6. 获取帮助及寻找文档.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "> 作者:Emmanuelle Gouillart" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "与了解Numpy和Scipy中的所有函数相比,通过文档和可用的帮助快捷地找到信息更重要。这里是获得信息的一些方式:\n", 15 | "\n", 16 | "- 在Ipython中,`help 方法`打开函数的文档字符串。只需要输入函数名的起始字母,使用tab完成来显示匹配到的函数。\n", 17 | "\n", 18 | "```python\n", 19 | "In [204]: help np.v\n", 20 | "np.vander np.vdot np.version np.void0 np.vstack\n", 21 | "np.var np.vectorize np.void np.vsplit\n", 22 | "\n", 23 | "In [204]: help np.vander\n", 24 | "\n", 25 | "```\n", 26 | "\n", 27 | "在Ipython中无法为帮助和问答打开一个独立的窗口;但是,可以打开另一个Ipython shell仅显示帮助和文档字符串...\n", 28 | "\n", 29 | "- Numpy和Scipy的文档可以在线查看http://docs.scipy.org/doc 。两个包的参考文档(http://docs.scipy.org/doc/numpy/reference/ 和 http://docs.scipy.org/doc/scipy/reference/) 中的搜索按钮非常有用。\n", 30 | "\n", 31 | "在这个网站上也可以找到不同主题的教程以及所有文档完整的API。\n", 32 | "![](http://www.scipy-lectures.org/_images/scipy_doc.png)\n", 33 | "\n", 34 | "- Numpy和Scipy的文档由用户在wiki http://docs.scipy.org/doc/numpy/ 上定期丰富和更新。因此,一些API文档(docstrings)在wiki上更清晰 详尽,你可能更想在wiki上读取文档而不是在官方文档网站上。注意任何人都可以在wiki上创建一个帐号来写更好的文档;这是为开源项目做贡献以及改善你所使用的工具的简单方式!\n", 35 | "\n", 36 | "![](http://www.scipy-lectures.org/_images/docwiki.png)\n", 37 | "\n", 38 | "- Scipy central http://central.scipy.org/ 给出了许多常见问题的做法,比如拟合数据点,求解ODE等。\n", 39 | "\n", 40 | "- Matplotlib网站 http://matplotlib.org/ 以一个拥有大量图表的非常漂亮的***画廊***为特色,每个图表都显示了源代码及生成的图表。这对于通过例子来学习非常有帮助。在网站上也可以找到更多的标准文档。\n", 41 | "\n", 42 | "![](http://www.scipy-lectures.org/_images/matplotlib.png)\n", 43 | "\n", 44 | "\n", 45 | "最后,两个更加“技术”的可能性也非常有用:\n", 46 | "\n", 47 | "- 在Ipython中,魔法函数`%psearch`搜索匹配模式的对象。例如,如果不知道函数的准确名称,这将非常有用。\n", 48 | "\n", 49 | "```python\n", 50 | "\n", 51 | "In [3]: import numpy as np\n", 52 | "In [4]: %psearch np.diag*\n", 53 | "np.diag\n", 54 | "np.diagflat\n", 55 | "np.diagonal\n", 56 | "\n", 57 | "```\n", 58 | "\n", 59 | "- `numpy.lookfor` 查找指定模块文档字符串中的关键字。\n", 60 | "\n", 61 | "```python\n", 62 | "\n", 63 | "In [45]: numpy.lookfor('convolution')\n", 64 | "Search results for 'convolution'\n", 65 | "--------------------------------\n", 66 | "numpy.convolve\n", 67 | " Returns the discrete, linear convolution of two one-dimensional\n", 68 | "sequences.\n", 69 | "numpy.bartlett\n", 70 | " Return the Bartlett window.\n", 71 | "numpy.correlate\n", 72 | " Discrete, linear correlation of two 1-dimensional sequences.\n", 73 | "In [46]: numpy.lookfor('remove', module='os')\n", 74 | "Search results for 'remove'\n", 75 | "---------------------------\n", 76 | "os.remove\n", 77 | " remove(path)\n", 78 | "os.removedirs\n", 79 | " removedirs(path)\n", 80 | "os.rmdir\n", 81 | " rmdir(path)\n", 82 | "os.unlink\n", 83 | " unlink(path)\n", 84 | "os.walk\n", 85 | " Directory tree generator.\n", 86 | "\n", 87 | "```\n", 88 | "\n", 89 | "\n", 90 | "- 如果上面列出的所有方法都失败了(并且Google也没有答案)... 不要绝望!你的问题适合向邮件组写一封邮件:如果你很好的描述了你的问题,那么你应该会很快得到答案。Python科学计算的专家经常通过邮件组给出非常有启发性的解释。\n", 91 | " - Numpy讨论(numpy-discussion@scipy.org): 全部是关于Numpy数组,操作数据,索引等问题。\n", 92 | " - SciPy用户列表(scipy-user@scipy.org): 用Python进行科学计算,高级数据处理,特别是scipy包的使用。\n", 93 | " - [matplotlib-users@lists.sourceforge.net](matplotlib-users@lists.sourceforge.net) 用matplotlib绘图。" 94 | ] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "execution_count": null, 99 | "metadata": { 100 | "collapsed": true 101 | }, 102 | "outputs": [], 103 | "source": [] 104 | } 105 | ], 106 | "metadata": { 107 | "kernelspec": { 108 | "display_name": "Python 3", 109 | "language": "python", 110 | "name": "python3" 111 | }, 112 | "language_info": { 113 | "codemirror_mode": { 114 | "name": "ipython", 115 | "version": 3 116 | }, 117 | "file_extension": ".py", 118 | "mimetype": "text/x-python", 119 | "name": "python", 120 | "nbconvert_exporter": "python", 121 | "pygments_lexer": "ipython3", 122 | "version": "3.6.1" 123 | }, 124 | "toc": { 125 | "colors": { 126 | "hover_highlight": "#DAA520", 127 | "navigate_num": "#000000", 128 | "navigate_text": "#333333", 129 | "running_highlight": "#FF0000", 130 | "selected_highlight": "#FFD700", 131 | "sidebar_border": "#EEEEEE", 132 | "wrapper_background": "#FFFFFF" 133 | }, 134 | "moveMenuLeft": true, 135 | "nav_menu": { 136 | "height": "12px", 137 | "width": "252px" 138 | }, 139 | "navigate_menu": true, 140 | "number_sections": true, 141 | "sideBar": true, 142 | "threshold": 4, 143 | "toc_cell": false, 144 | "toc_section_display": "block", 145 | "toc_window_display": false, 146 | "widenNotebook": false 147 | } 148 | }, 149 | "nbformat": 4, 150 | "nbformat_minor": 1 151 | } 152 | -------------------------------------------------------------------------------- /2.4. 代码优化.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "%matplotlib inline\n", 12 | "import numpy as np" 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": {}, 18 | "source": [ 19 | "---\n", 20 | "\n", 21 | "**作者**:Gaël Varoquaux\n", 22 | "\n", 23 | "**Donald Knuth**\n", 24 | "\n", 25 | "\"过早的优化是一切罪恶的根源\"\n", 26 | "\n", 27 | "---\n", 28 | "\n", 29 | "本章处理用策略让Python代码跑得更快。\n", 30 | "\n", 31 | "---\n", 32 | "\n", 33 | "**先决条件**\n", 34 | "\n", 35 | "- line_profiler\n", 36 | "- gprof2dot\n", 37 | "- 来自dot实用程序\n", 38 | "\n", 39 | "---\n", 40 | "\n", 41 | "---\n", 42 | "\n", 43 | "**章节内容**\n", 44 | "\n", 45 | "- 优化工作流\n", 46 | "- 剖析Python代码\n", 47 | " - Timeit\n", 48 | " - Profiler\n", 49 | " - Line-profiler\n", 50 | " - Running `cProfile`\n", 51 | " - Using `gprof2dot`\n", 52 | "- 让代码更快\n", 53 | " - 算法优化\n", 54 | " - SVD的例子\n", 55 | "- 写更快的数值代码\n", 56 | " - 其他的链接\n", 57 | "\n", 58 | "## 2.4.1 优化工作流\n", 59 | "\n", 60 | "1. 让它工作起来:用简单清晰的方式来写代码。\n", 61 | "2. 让它可靠的工作:写自动的测试案例,以便真正确保你的算法是正确的,并且如果你破坏它,测试会捕捉到。\n", 62 | "3. 通过剖析简单的使用案例找到瓶颈,并且加速这些瓶颈,寻找更好的算法或实现方式来优化代码。记住在剖析现实例子时简单和代码的执行速度需要进行一个权衡。要有效的运行,最好让剖析工作持续10s左右。\n", 63 | "\n", 64 | "## 2.4.2剖析Python代码\n", 65 | "\n", 66 | "**无测量无优化!**\n", 67 | "\n", 68 | "- **测量**: 剖析, 计时\n", 69 | "- 你可能会惊讶:最快的代码并不是通常你想的样子\n", 70 | "\n", 71 | "### 2.4.2.1 Timeit\n", 72 | "在IPython中,使用timeit(http://docs.python.org/library/timeit.html)来计时基本的操作:" 73 | ] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "execution_count": 2, 78 | "metadata": { 79 | "collapsed": false 80 | }, 81 | "outputs": [ 82 | { 83 | "name": "stdout", 84 | "output_type": "stream", 85 | "text": [ 86 | "The slowest run took 60.37 times longer than the fastest. This could mean that an intermediate result is being cached \n", 87 | "100000 loops, best of 3: 1.99 µs per loop\n" 88 | ] 89 | } 90 | ], 91 | "source": [ 92 | "import numpy as np\n", 93 | "\n", 94 | "a = np.arange(1000)\n", 95 | "\n", 96 | "%timeit a ** 2" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": 3, 102 | "metadata": { 103 | "collapsed": false 104 | }, 105 | "outputs": [ 106 | { 107 | "name": "stdout", 108 | "output_type": "stream", 109 | "text": [ 110 | "10000 loops, best of 3: 45.1 µs per loop\n" 111 | ] 112 | } 113 | ], 114 | "source": [ 115 | "%timeit a ** 2.1" 116 | ] 117 | }, 118 | { 119 | "cell_type": "code", 120 | "execution_count": 4, 121 | "metadata": { 122 | "collapsed": false 123 | }, 124 | "outputs": [ 125 | { 126 | "name": "stdout", 127 | "output_type": "stream", 128 | "text": [ 129 | "The slowest run took 12.79 times longer than the fastest. This could mean that an intermediate result is being cached \n", 130 | "100000 loops, best of 3: 1.86 µs per loop\n" 131 | ] 132 | } 133 | ], 134 | "source": [ 135 | "%timeit a * a" 136 | ] 137 | }, 138 | { 139 | "cell_type": "markdown", 140 | "metadata": {}, 141 | "source": [ 142 | "用这个信息来指导在不同策略间进行选择。\n", 143 | "\n", 144 | "---\n", 145 | "\n", 146 | "**笔记**:对于运行时间较长的单元,使用`%time`来代替`%timeit`; 它准确性较差但是更快。\n", 147 | "\n", 148 | "---\n", 149 | "\n", 150 | "### 2.4.2.2 Profiler\n", 151 | "\n", 152 | "当你有个大型程序要剖析时比较有用,例如[下面这个程序](http://scipy-lectures.github.io/_downloads/demo.py):" 153 | ] 154 | }, 155 | { 156 | "cell_type": "code", 157 | "execution_count": null, 158 | "metadata": { 159 | "collapsed": true 160 | }, 161 | "outputs": [], 162 | "source": [ 163 | "# For this example to run, you also need the 'ica.py' file\n", 164 | "\n", 165 | "import numpy as np\n", 166 | "from scipy import linalg\n", 167 | "\n", 168 | "from ica import fastica\n", 169 | "\n", 170 | "\n", 171 | "def test():\n", 172 | " data = np.random.random((5000, 100))\n", 173 | " u, s, v = linalg.svd(data)\n", 174 | " pca = np.dot(u[:, :10].T, data)\n", 175 | " results = fastica(pca.T, whiten=False)\n", 176 | "\n", 177 | "if __name__ == '__main__':\n", 178 | " test()" 179 | ] 180 | }, 181 | { 182 | "cell_type": "markdown", 183 | "metadata": {}, 184 | "source": [ 185 | "---\n", 186 | "**笔记**:这种技术是两个非监督学习技术的组合,主成分分析(PCA)和独立成分分析([ICA](http://scipy-lectures.github.io/advanced/optimizing/index.html#id16))。PCA是一种降维技术,即一种用更少的维度解释数据中观察到的变异的算法。ICA是一种源信号分离技术,例如分离由多个传感器记录的多种信号。如果传感器比信号多,那么先进行PCA然后ICA会有帮助。更多的信息请见:[来自scikits-learn的FastICA例子](http://scikit-learn.org/stable/auto_examples/decomposition/plot_ica_blind_source_separation.html)。\n", 187 | "\n", 188 | "---\n", 189 | "\n", 190 | "要运行它,你也需要下载[ica模块](http://scipy-lectures.github.io/_downloads/ica.py)。在IPython我们计时这个脚本:" 191 | ] 192 | }, 193 | { 194 | "cell_type": "code", 195 | "execution_count": 8, 196 | "metadata": { 197 | "collapsed": false 198 | }, 199 | "outputs": [ 200 | { 201 | "name": "stdout", 202 | "output_type": "stream", 203 | "text": [ 204 | "\n", 205 | "IPython CPU timings (estimated):\n", 206 | " User : 6.62 s.\n", 207 | " System : 0.17 s.\n", 208 | "Wall time: 3.72 s.\n" 209 | ] 210 | }, 211 | { 212 | "name": "stderr", 213 | "output_type": "stream", 214 | "text": [ 215 | "/Users/cloga/Documents/scipy-lecture-notes_cn/ica.py:65: RuntimeWarning: invalid value encountered in sqrt\n", 216 | " W = (u * np.diag(1.0/np.sqrt(s)) * u.T) * W # W = (W * W.T) ^{-1/2} * W\n", 217 | "/Users/cloga/Documents/scipy-lecture-notes_cn/ica.py:90: RuntimeWarning: invalid value encountered in absolute\n", 218 | " lim = max(abs(abs(np.diag(np.dot(W1, W.T))) - 1))\n" 219 | ] 220 | } 221 | ], 222 | "source": [ 223 | "%run -t demo.py" 224 | ] 225 | }, 226 | { 227 | "cell_type": "markdown", 228 | "metadata": {}, 229 | "source": [ 230 | "并且剖析它:\n", 231 | "\n", 232 | "```\n", 233 | "%run -p demo.py\n", 234 | "\n", 235 | " 301 function calls in 3.746 seconds\n", 236 | "\n", 237 | " Ordered by: internal time\n", 238 | "\n", 239 | " ncalls tottime percall cumtime percall filename:lineno(function)\n", 240 | " 1 3.714 3.714 3.715 3.715 decomp_svd.py:15(svd)\n", 241 | " 1 0.019 0.019 3.745 3.745 demo.py:3()\n", 242 | " 1 0.007 0.007 0.007 0.007 {method 'random_sample' of 'mtrand.RandomState' objects}\n", 243 | " 14 0.003 0.000 0.003 0.000 {numpy.core._dotblas.dot}\n", 244 | " 1 0.001 0.001 0.001 0.001 function_base.py:550(asarray_chkfinite)\n", 245 | " 2 0.000 0.000 0.000 0.000 linalg.py:1116(eigh)\n", 246 | " 1 0.000 0.000 3.745 3.745 {execfile}\n", 247 | " 2 0.000 0.000 0.001 0.000 ica.py:58(_sym_decorrelation)\n", 248 | " 2 0.000 0.000 0.000 0.000 {method 'reduce' of 'numpy.ufunc' objects}\n", 249 | " 1 0.000 0.000 0.000 0.000 ica.py:195(gprime)\n", 250 | " 1 0.000 0.000 0.001 0.001 ica.py:69(_ica_par)\n", 251 | " 1 0.000 0.000 3.726 3.726 demo.py:9(test)\n", 252 | " 1 0.000 0.000 0.001 0.001 ica.py:97(fastica)\n", 253 | " 1 0.000 0.000 0.000 0.000 ica.py:192(g)\n", 254 | " 23 0.000 0.000 0.000 0.000 defmatrix.py:290(__array_finalize__)\n", 255 | " 4 0.000 0.000 0.000 0.000 twodim_base.py:242(diag)\n", 256 | " 1 0.000 0.000 3.746 3.746 interactiveshell.py:2616(safe_execfile)\n", 257 | " 10 0.000 0.000 0.000 0.000 {numpy.core.multiarray.array}\n", 258 | " 1 0.000 0.000 3.745 3.745 py3compat.py:279(execfile)\n", 259 | " 1 0.000 0.000 0.000 0.000 {method 'normal' of 'mtrand.RandomState' objects}\n", 260 | " 50 0.000 0.000 0.000 0.000 {isinstance}\n", 261 | " 10 0.000 0.000 0.000 0.000 defmatrix.py:66(asmatrix)\n", 262 | " 10 0.000 0.000 0.000 0.000 defmatrix.py:244(__new__)\n", 263 | " 9 0.000 0.000 0.000 0.000 numeric.py:394(asarray)\n", 264 | " 1 0.000 0.000 0.000 0.000 _methods.py:53(_mean)\n", 265 | " 1 0.000 0.000 0.000 0.000 {posix.getcwdu}\n", 266 | " 4 0.000 0.000 0.000 0.000 {method 'astype' of 'numpy.ndarray' objects}\n", 267 | " 6 0.000 0.000 0.000 0.000 defmatrix.py:338(__mul__)\n", 268 | " 2 0.000 0.000 0.000 0.000 linalg.py:139(_commonType)\n", 269 | " 4 0.000 0.000 0.000 0.000 {method 'view' of 'numpy.ndarray' objects}\n", 270 | " 1 0.000 0.000 0.000 0.000 posixpath.py:329(normpath)\n", 271 | " 5 0.000 0.000 0.000 0.000 {abs}\n", 272 | " 1 0.000 0.000 0.000 0.000 {open}\n", 273 | " 1 0.000 0.000 0.000 0.000 blas.py:172(find_best_blas_type)\n", 274 | " 1 0.000 0.000 0.000 0.000 blas.py:216(_get_funcs)\n", 275 | " 1 0.000 0.000 0.000 0.000 syspathcontext.py:64(__exit__)\n", 276 | " 3 0.000 0.000 0.000 0.000 {max}\n", 277 | " 6 0.000 0.000 0.000 0.000 {method 'transpose' of 'numpy.ndarray' objects}\n", 278 | " 1 0.000 0.000 0.000 0.000 posixpath.py:120(dirname)\n", 279 | " 2 0.000 0.000 0.000 0.000 linalg.py:101(get_linalg_error_extobj)\n", 280 | " 2 0.000 0.000 0.000 0.000 linalg.py:106(_makearray)\n", 281 | " 3 0.000 0.000 0.000 0.000 {numpy.core.multiarray.zeros}\n", 282 | " 6 0.000 0.000 0.000 0.000 defmatrix.py:928(getT)\n", 283 | " 1 0.000 0.000 0.000 0.000 syspathcontext.py:57(__enter__)\n", 284 | " 2 0.000 0.000 0.000 0.000 linalg.py:209(_assertNdSquareness)\n", 285 | " 7 0.000 0.000 0.000 0.000 {issubclass}\n", 286 | " 4 0.000 0.000 0.000 0.000 {getattr}\n", 287 | " 1 0.000 0.000 0.000 0.000 posixpath.py:358(abspath)\n", 288 | " 5 0.000 0.000 0.000 0.000 {method 'startswith' of 'unicode' objects}\n", 289 | " 2 0.000 0.000 0.000 0.000 linalg.py:198(_assertRankAtLeast2)\n", 290 | " 2 0.000 0.000 0.000 0.000 {method 'encode' of 'unicode' objects}\n", 291 | " 10 0.000 0.000 0.000 0.000 {method 'get' of 'dict' objects}\n", 292 | " 1 0.000 0.000 0.000 0.000 _methods.py:43(_count_reduce_items)\n", 293 | " 1 0.000 0.000 0.000 0.000 {method 'all' of 'numpy.ndarray' objects}\n", 294 | " 4 0.000 0.000 0.000 0.000 linalg.py:124(_realType)\n", 295 | " 1 0.000 0.000 0.000 0.000 syspathcontext.py:54(__init__)\n", 296 | " 1 0.000 0.000 0.000 0.000 posixpath.py:61(join)\n", 297 | " 1 0.000 0.000 3.746 3.746 :1()\n", 298 | " 1 0.000 0.000 0.000 0.000 _methods.py:40(_all)\n", 299 | " 4 0.000 0.000 0.000 0.000 linalg.py:111(isComplexType)\n", 300 | " 2 0.000 0.000 0.000 0.000 {method '__array_prepare__' of 'numpy.ndarray' objects}\n", 301 | " 4 0.000 0.000 0.000 0.000 {min}\n", 302 | " 1 0.000 0.000 0.000 0.000 py3compat.py:19(encode)\n", 303 | " 1 0.000 0.000 0.000 0.000 defmatrix.py:872(getA)\n", 304 | " 2 0.000 0.000 0.000 0.000 numerictypes.py:949(_can_coerce_all)\n", 305 | " 6 0.000 0.000 0.000 0.000 {method 'append' of 'list' objects}\n", 306 | " 1 0.000 0.000 0.000 0.000 numerictypes.py:970(find_common_type)\n", 307 | " 1 0.000 0.000 0.000 0.000 {method 'mean' of 'numpy.ndarray' objects}\n", 308 | " 11 0.000 0.000 0.000 0.000 {len}\n", 309 | " 1 0.000 0.000 0.000 0.000 numeric.py:464(asanyarray)\n", 310 | " 1 0.000 0.000 0.000 0.000 {method '__array__' of 'numpy.ndarray' objects}\n", 311 | " 1 0.000 0.000 0.000 0.000 {method 'rfind' of 'unicode' objects}\n", 312 | " 2 0.000 0.000 0.000 0.000 {method 'upper' of 'str' objects}\n", 313 | " 1 0.000 0.000 0.000 0.000 posixpath.py:251(expanduser)\n", 314 | " 3 0.000 0.000 0.000 0.000 {method 'setdefault' of 'dict' objects}\n", 315 | " 1 0.000 0.000 0.000 0.000 {method 'diagonal' of 'numpy.ndarray' objects}\n", 316 | " 1 0.000 0.000 0.000 0.000 lapack.py:239(get_lapack_funcs)\n", 317 | " 1 0.000 0.000 0.000 0.000 {method 'rstrip' of 'unicode' objects}\n", 318 | " 1 0.000 0.000 0.000 0.000 py3compat.py:29(cast_bytes)\n", 319 | " 1 0.000 0.000 0.000 0.000 posixpath.py:52(isabs)\n", 320 | " 1 0.000 0.000 0.000 0.000 {method 'split' of 'unicode' objects}\n", 321 | " 1 0.000 0.000 0.000 0.000 {method 'endswith' of 'unicode' objects}\n", 322 | " 1 0.000 0.000 0.000 0.000 {sys.getdefaultencoding}\n", 323 | " 1 0.000 0.000 0.000 0.000 {method 'insert' of 'list' objects}\n", 324 | " 1 0.000 0.000 0.000 0.000 {method 'remove' of 'list' objects}\n", 325 | " 1 0.000 0.000 0.000 0.000 {method 'join' of 'unicode' objects}\n", 326 | " 1 0.000 0.000 0.000 0.000 {method 'index' of 'list' objects}\n", 327 | " 1 0.000 0.000 0.000 0.000 misc.py:126(_datacopied)\n", 328 | " 1 0.000 0.000 0.000 0.000 {sys.getfilesystemencoding}\n", 329 | " 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}\n", 330 | "```\n", 331 | "\n", 332 | "很明显`svd`(**decomp.py**中)占用了最多的时间,换句话说,是瓶颈。我们要找到方法让这个步骤跑的更快,或者避免这个步骤(算法优化)。在其他部分花费时间是没用的。\n", 333 | "\n", 334 | "### 2.4.2.3 Line-profiler\n", 335 | "\n", 336 | "profiler很棒:它告诉我们哪个函数花费了最多的时间,但是,不是它在哪里被调用。\n", 337 | "\n", 338 | "关于这一点,我们使用[line_profiler](http://packages.python.org/line_profiler/):在源文件中,我们用@profile(不需要导入它)修饰了一些想要用检查的函数:" 339 | ] 340 | }, 341 | { 342 | "cell_type": "code", 343 | "execution_count": null, 344 | "metadata": { 345 | "collapsed": true 346 | }, 347 | "outputs": [], 348 | "source": [ 349 | "@profile\n", 350 | "def test():\n", 351 | " data = np.random.random((5000, 100))\n", 352 | " u, s, v = linalg.svd(data)\n", 353 | " pca = np.dot(u[: , :10], data)\n", 354 | " results = fastica(pca.T, whiten=False)" 355 | ] 356 | }, 357 | { 358 | "cell_type": "markdown", 359 | "metadata": {}, 360 | "source": [ 361 | "接着我们用[kernprof.py](http://packages.python.org/line_profiler/kernprof.py)来运行这个脚本,开启`-l, --line-by-line`和`-v, --view`来使用逐行profiler,并且查看结果并保存他们:\n", 362 | "\n", 363 | "```\n", 364 | "kernprof.py -l -v demo.py\n", 365 | "\n", 366 | "Wrote profile results to demo.py.lprof\n", 367 | "Timer unit: 1e-06 s\n", 368 | "\n", 369 | "File: demo.py\n", 370 | "Function: test at line 5\n", 371 | "Total time: 14.2793 s\n", 372 | "\n", 373 | "Line # Hits Time Per Hit % Time Line Contents\n", 374 | "==============================================================\n", 375 | " 5 @profile\n", 376 | " 6 def test():\n", 377 | " 7 1 19015 19015.0 0.1 data = np.random.random((5000, 100))\n", 378 | " 8 1 14242163 14242163.0 99.7 u, s, v = linalg.svd(data)\n", 379 | " 9 1 10282 10282.0 0.1 pca = np.dot(u[:10, :], data)\n", 380 | " 10 1 7799 7799.0 0.1 results = fastica(pca.T, whiten=False)\n", 381 | "\n", 382 | "```\n", 383 | "\n", 384 | "SVD占用了几乎所有时间,我们需要优化这一行。\n", 385 | "\n", 386 | "### 2.4.2.4 运行`cProfile`\n", 387 | "\n", 388 | "在上面的IPython例子中,Ipython只是调用了内置的[Python剖析器](http://docs.python.org/2/library/profile.html)`cProfile`和`profile`。如果你想要用一个可视化工具来处理剖析器的结果,这会有帮助。\n", 389 | "\n", 390 | "```\n", 391 | "python -m cProfile -o demo.prof demo.py\n", 392 | "```\n", 393 | "\n", 394 | "使用`-o`开关将输入剖析器结果到文件`demo.prof`。\n", 395 | "\n", 396 | "### 2.4.2.5 使用`gprof2dot`\n", 397 | "\n", 398 | "如果你想要更加视觉化的剖析器输入结果,你可以使用[gprof2dot](http://code.google.com/p/jrfonseca/wiki/Gprof2Dot)工具:" 399 | ] 400 | }, 401 | { 402 | "cell_type": "code", 403 | "execution_count": null, 404 | "metadata": { 405 | "collapsed": true 406 | }, 407 | "outputs": [], 408 | "source": [ 409 | "gprof2dot -f pstats demo.prof | dot -Tpng -o demo-prof.png" 410 | ] 411 | }, 412 | { 413 | "cell_type": "markdown", 414 | "metadata": {}, 415 | "source": [ 416 | "这会生成下面的图片:\n", 417 | "\n", 418 | "![](http://scipy-lectures.github.io/_images/demo-prof.png)\n", 419 | "\n", 420 | "这种方法打印了一个类似前一种方法的图片。\n", 421 | "\n", 422 | "## 2.4.3 让代码更快\n", 423 | "\n", 424 | "一旦我们识别出瓶颈,我们需要让相关的代码跑得更快。\n", 425 | "\n", 426 | "### 2.4.3.1 算法优化\n", 427 | "\n", 428 | "第一件要看的事情是算法优化:有没有计算量更小的方法或者更好的方法?\n", 429 | "\n", 430 | "从更高的视角来看这个问题,对算法背后的数学有一个很好的理解会有帮助。但是,寻找到像**将计算或内存分配移到循环外**这样的简单改变,来带来巨大的收益,通常很困难。\n", 431 | "\n", 432 | "#### 2.4.3.1.1 SVD的例子\n", 433 | "\n", 434 | "在上面的两个例子中,SVD - [奇异值分解](http://en.wikipedia.org/wiki/Singular_value_decomposition) - 花费了最多的时间。确实,这个算法的计算成本大概是输入矩阵大小的$n^3$。\n", 435 | "\n", 436 | "但是,在这些例子中,我们并不是使用SVD的所有输出,而只是它第一个返回参数的前几行。如果我们使用scipy的`svd`实现,我们可以请求一个这个SVD的不完整版本。注意scipy中的线性代数实现比在numpy中更丰富,应该被优选选用。" 437 | ] 438 | }, 439 | { 440 | "cell_type": "code", 441 | "execution_count": 20, 442 | "metadata": { 443 | "collapsed": false 444 | }, 445 | "outputs": [ 446 | { 447 | "name": "stdout", 448 | "output_type": "stream", 449 | "text": [ 450 | "1 loops, best of 3: 4.12 s per loop\n" 451 | ] 452 | } 453 | ], 454 | "source": [ 455 | "%timeit np.linalg.svd(data)" 456 | ] 457 | }, 458 | { 459 | "cell_type": "code", 460 | "execution_count": 21, 461 | "metadata": { 462 | "collapsed": false 463 | }, 464 | "outputs": [ 465 | { 466 | "name": "stdout", 467 | "output_type": "stream", 468 | "text": [ 469 | "1 loops, best of 3: 3.65 s per loop\n" 470 | ] 471 | } 472 | ], 473 | "source": [ 474 | "from scipy import linalg\n", 475 | "%timeit linalg.svd(data)" 476 | ] 477 | }, 478 | { 479 | "cell_type": "code", 480 | "execution_count": 22, 481 | "metadata": { 482 | "collapsed": false 483 | }, 484 | "outputs": [ 485 | { 486 | "name": "stdout", 487 | "output_type": "stream", 488 | "text": [ 489 | "10 loops, best of 3: 70.5 ms per loop\n" 490 | ] 491 | } 492 | ], 493 | "source": [ 494 | "%timeit linalg.svd(data, full_matrices=False)" 495 | ] 496 | }, 497 | { 498 | "cell_type": "code", 499 | "execution_count": 23, 500 | "metadata": { 501 | "collapsed": false 502 | }, 503 | "outputs": [ 504 | { 505 | "name": "stdout", 506 | "output_type": "stream", 507 | "text": [ 508 | "10 loops, best of 3: 70.3 ms per loop\n" 509 | ] 510 | } 511 | ], 512 | "source": [ 513 | "%timeit np.linalg.svd(data, full_matrices=False)" 514 | ] 515 | }, 516 | { 517 | "cell_type": "markdown", 518 | "metadata": {}, 519 | "source": [ 520 | "接下来我们可以用这个发现来[优化前面的代码](http://scipy-lectures.github.io/_downloads/demo_opt.py):" 521 | ] 522 | }, 523 | { 524 | "cell_type": "code", 525 | "execution_count": 24, 526 | "metadata": { 527 | "collapsed": true 528 | }, 529 | "outputs": [], 530 | "source": [ 531 | "import demo" 532 | ] 533 | }, 534 | { 535 | "cell_type": "code", 536 | "execution_count": 27, 537 | "metadata": { 538 | "collapsed": false 539 | }, 540 | "outputs": [ 541 | { 542 | "name": "stdout", 543 | "output_type": "stream", 544 | "text": [ 545 | "1 loops, best of 3: 3.65 s per loop\n" 546 | ] 547 | } 548 | ], 549 | "source": [ 550 | "%timeit demo.test()" 551 | ] 552 | }, 553 | { 554 | "cell_type": "code", 555 | "execution_count": 28, 556 | "metadata": { 557 | "collapsed": true 558 | }, 559 | "outputs": [], 560 | "source": [ 561 | "import demo_opt" 562 | ] 563 | }, 564 | { 565 | "cell_type": "code", 566 | "execution_count": 29, 567 | "metadata": { 568 | "collapsed": false 569 | }, 570 | "outputs": [ 571 | { 572 | "name": "stdout", 573 | "output_type": "stream", 574 | "text": [ 575 | "10 loops, best of 3: 81.9 ms per loop\n" 576 | ] 577 | } 578 | ], 579 | "source": [ 580 | "%timeit demo_opt.test()" 581 | ] 582 | }, 583 | { 584 | "cell_type": "markdown", 585 | "metadata": {}, 586 | "source": [ 587 | "真实的非完整版SVD,即只计算前十个特征向量,可以用arpack来计算,可以在`scipy.sparse.linalg.eigsh`找到。\n", 588 | "\n", 589 | "---\n", 590 | "**计算线性代数**\n", 591 | "\n", 592 | "对于特定的算法,许多瓶颈会是线性代数计算。在这种情况下,使用正确的方法来解决正确的问题是关键。例如一个对称矩阵中的特征向量问题比通用矩阵中更好解决。同样,更普遍的是,你可以避免矩阵逆转,使用一些成本更低(在数字上更可靠)的操作。\n", 593 | "\n", 594 | "了解你的计算线性代数。当有疑问时,查找`scipy.linalg`,并且用`%timeit`来试一下替代方案。\n", 595 | "\n", 596 | "## 2.4.4 写更快的数值代码\n", 597 | "\n", 598 | "关于numpy的高级使用的讨论可以在[高级numpy](http://scipy-lectures.github.io/advanced/advanced_numpy/index.html#advanced-numpy)那章,或者由van der Walt等所写的文章[NumPy数组: 一种高效数值计算结构](http://hal.inria.fr/inria-00564007/en)。这里只是一些经常会遇到的让代码更快的小技巧。\n", 599 | "\n", 600 | "- 循环向量化\n", 601 | "\n", 602 | " 找到一些技巧来用numpy数组避免循环。对于这一点,掩蔽和索引通常很有用。\n", 603 | "\n", 604 | "- 广播\n", 605 | "\n", 606 | " 在数组合并前,在尽可能小的数组上使用广播。\n", 607 | "\n", 608 | "- 原地操作" 609 | ] 610 | }, 611 | { 612 | "cell_type": "code", 613 | "execution_count": 30, 614 | "metadata": { 615 | "collapsed": false 616 | }, 617 | "outputs": [ 618 | { 619 | "name": "stdout", 620 | "output_type": "stream", 621 | "text": [ 622 | "10 loops, best of 3: 33.5 ms per loop\n" 623 | ] 624 | }, 625 | { 626 | "name": "stderr", 627 | "output_type": "stream", 628 | "text": [ 629 | "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ipykernel/__main__.py:1: DeprecationWarning: using a non-integer number instead of an integer will result in an error in the future\n", 630 | " if __name__ == '__main__':\n" 631 | ] 632 | } 633 | ], 634 | "source": [ 635 | "a = np.zeros(1e7)\n", 636 | "\n", 637 | "%timeit global a ; a = 0*a" 638 | ] 639 | }, 640 | { 641 | "cell_type": "code", 642 | "execution_count": 31, 643 | "metadata": { 644 | "collapsed": false 645 | }, 646 | "outputs": [ 647 | { 648 | "name": "stdout", 649 | "output_type": "stream", 650 | "text": [ 651 | "100 loops, best of 3: 8.98 ms per loop\n" 652 | ] 653 | } 654 | ], 655 | "source": [ 656 | "%timeit global a ; a *= 0" 657 | ] 658 | }, 659 | { 660 | "cell_type": "markdown", 661 | "metadata": {}, 662 | "source": [ 663 | "**注意**: 我们需要在timeit中`global a`,以便正常工作,因为,向a赋值,会被认为是一个本地变量。\n", 664 | "\n", 665 | "- 对内存好一点:使用视图而不是副本\n", 666 | "\n", 667 | "复制一个大数组和在上面进行简单的数值运算一样代价昂贵:" 668 | ] 669 | }, 670 | { 671 | "cell_type": "code", 672 | "execution_count": 32, 673 | "metadata": { 674 | "collapsed": false 675 | }, 676 | "outputs": [ 677 | { 678 | "name": "stderr", 679 | "output_type": "stream", 680 | "text": [ 681 | "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ipykernel/__main__.py:1: DeprecationWarning: using a non-integer number instead of an integer will result in an error in the future\n", 682 | " if __name__ == '__main__':\n" 683 | ] 684 | } 685 | ], 686 | "source": [ 687 | "a = np.zeros(1e7)" 688 | ] 689 | }, 690 | { 691 | "cell_type": "code", 692 | "execution_count": 33, 693 | "metadata": { 694 | "collapsed": false 695 | }, 696 | "outputs": [ 697 | { 698 | "name": "stdout", 699 | "output_type": "stream", 700 | "text": [ 701 | "10 loops, best of 3: 28.2 ms per loop\n" 702 | ] 703 | } 704 | ], 705 | "source": [ 706 | "%timeit a.copy()" 707 | ] 708 | }, 709 | { 710 | "cell_type": "code", 711 | "execution_count": 34, 712 | "metadata": { 713 | "collapsed": false 714 | }, 715 | "outputs": [ 716 | { 717 | "name": "stdout", 718 | "output_type": "stream", 719 | "text": [ 720 | "10 loops, best of 3: 33.4 ms per loop\n" 721 | ] 722 | } 723 | ], 724 | "source": [ 725 | "%timeit a + 1" 726 | ] 727 | }, 728 | { 729 | "cell_type": "markdown", 730 | "metadata": {}, 731 | "source": [ 732 | "- 注意缓存作用\n", 733 | "\n", 734 | " 分组后内存访问代价很低:用连续的方式访问一个大数组比随机访问快很多。这意味着在其他方式中小步幅会更快(见[CPU缓存作用](http://scipy-lectures.github.io/advanced/advanced_numpy/index.html#cache-effects)):" 735 | ] 736 | }, 737 | { 738 | "cell_type": "code", 739 | "execution_count": 35, 740 | "metadata": { 741 | "collapsed": false 742 | }, 743 | "outputs": [ 744 | { 745 | "name": "stderr", 746 | "output_type": "stream", 747 | "text": [ 748 | "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ipykernel/__main__.py:1: DeprecationWarning: using a non-integer number instead of an integer will result in an error in the future\n", 749 | " if __name__ == '__main__':\n" 750 | ] 751 | } 752 | ], 753 | "source": [ 754 | "c = np.zeros((1e4, 1e4), order='C')" 755 | ] 756 | }, 757 | { 758 | "cell_type": "code", 759 | "execution_count": 36, 760 | "metadata": { 761 | "collapsed": false 762 | }, 763 | "outputs": [ 764 | { 765 | "name": "stdout", 766 | "output_type": "stream", 767 | "text": [ 768 | "The slowest run took 5.66 times longer than the fastest. This could mean that an intermediate result is being cached \n", 769 | "1 loops, best of 3: 80.9 ms per loop\n" 770 | ] 771 | } 772 | ], 773 | "source": [ 774 | "%timeit c.sum(axis=0)" 775 | ] 776 | }, 777 | { 778 | "cell_type": "code", 779 | "execution_count": 37, 780 | "metadata": { 781 | "collapsed": false 782 | }, 783 | "outputs": [ 784 | { 785 | "name": "stdout", 786 | "output_type": "stream", 787 | "text": [ 788 | "10 loops, best of 3: 79.7 ms per loop\n" 789 | ] 790 | } 791 | ], 792 | "source": [ 793 | "%timeit c.sum(axis=1)" 794 | ] 795 | }, 796 | { 797 | "cell_type": "code", 798 | "execution_count": 38, 799 | "metadata": { 800 | "collapsed": false 801 | }, 802 | "outputs": [ 803 | { 804 | "data": { 805 | "text/plain": [ 806 | "(80000, 8)" 807 | ] 808 | }, 809 | "execution_count": 38, 810 | "metadata": {}, 811 | "output_type": "execute_result" 812 | } 813 | ], 814 | "source": [ 815 | "c.strides" 816 | ] 817 | }, 818 | { 819 | "cell_type": "markdown", 820 | "metadata": {}, 821 | "source": [ 822 | "这就是为什么Fortran顺序或者C顺序会在操作上有很大的不同:" 823 | ] 824 | }, 825 | { 826 | "cell_type": "code", 827 | "execution_count": 39, 828 | "metadata": { 829 | "collapsed": true 830 | }, 831 | "outputs": [], 832 | "source": [ 833 | "a = np.random.rand(20, 2**18)" 834 | ] 835 | }, 836 | { 837 | "cell_type": "code", 838 | "execution_count": 40, 839 | "metadata": { 840 | "collapsed": true 841 | }, 842 | "outputs": [], 843 | "source": [ 844 | "b = np.random.rand(20, 2**18)" 845 | ] 846 | }, 847 | { 848 | "cell_type": "code", 849 | "execution_count": 41, 850 | "metadata": { 851 | "collapsed": false 852 | }, 853 | "outputs": [ 854 | { 855 | "name": "stdout", 856 | "output_type": "stream", 857 | "text": [ 858 | "10 loops, best of 3: 23.8 ms per loop\n" 859 | ] 860 | } 861 | ], 862 | "source": [ 863 | "%timeit np.dot(b, a.T)" 864 | ] 865 | }, 866 | { 867 | "cell_type": "code", 868 | "execution_count": 42, 869 | "metadata": { 870 | "collapsed": true 871 | }, 872 | "outputs": [], 873 | "source": [ 874 | "c = np.ascontiguousarray(a.T)" 875 | ] 876 | }, 877 | { 878 | "cell_type": "code", 879 | "execution_count": 43, 880 | "metadata": { 881 | "collapsed": false 882 | }, 883 | "outputs": [ 884 | { 885 | "name": "stdout", 886 | "output_type": "stream", 887 | "text": [ 888 | "10 loops, best of 3: 22.2 ms per loop\n" 889 | ] 890 | } 891 | ], 892 | "source": [ 893 | "%timeit np.dot(b, c)" 894 | ] 895 | }, 896 | { 897 | "cell_type": "markdown", 898 | "metadata": {}, 899 | "source": [ 900 | "注意,通过复制数据来绕过这个效果是不值得的:" 901 | ] 902 | }, 903 | { 904 | "cell_type": "code", 905 | "execution_count": 44, 906 | "metadata": { 907 | "collapsed": false 908 | }, 909 | "outputs": [ 910 | { 911 | "name": "stdout", 912 | "output_type": "stream", 913 | "text": [ 914 | "10 loops, best of 3: 42.2 ms per loop\n" 915 | ] 916 | } 917 | ], 918 | "source": [ 919 | "%timeit c = np.ascontiguousarray(a.T)" 920 | ] 921 | }, 922 | { 923 | "cell_type": "markdown", 924 | "metadata": {}, 925 | "source": [ 926 | "使用[numexpr](http://code.google.com/p/numexpr/)可以帮助自动优化代码的这种效果。\n", 927 | "\n", 928 | "- 使用编译的代码\n", 929 | "\n", 930 | " 一旦你确定所有的高级优化都试过了,那么最后一招就是转移热点,即将最花费时间的几行或函数编译代码。要编译代码,优先选项是用使用[Cython](http://www.cython.org/):它可以简单的将Python代码转化为编译代码,并且很好的使用numpy支持来以numpy数据产出高效代码,例如通过展开循环。\n", 931 | "\n", 932 | "---\n", 933 | "**警告**:对于以上的技巧,剖析并计时你的选择。不要基于理论思考来优化。\n", 934 | "\n", 935 | "---\n", 936 | "\n", 937 | "### 2.4.4.1 其他的链接\n", 938 | "\n", 939 | "- 如果你需要剖析内存使用,你要应该试试[memory_profiler](http://pypi.python.org/pypi/memory_profiler)\n", 940 | "- 如果你需要剖析C扩展程序,你应该用[yep](http://pypi.python.org/pypi/yep)从Python中试着使用一下[gperftools](http://code.google.com/p/gperftools/?redir=1)。\n", 941 | "- 如果你想要持续跟踪代码的效率,比如随着你不断向代码库提交,你应该试一下:[vbench](https://github.com/pydata/vbench)\n", 942 | "- 如果你需要一些交互的可视化为什么不试一下[RunSnakeRun](http://www.vrplumber.com/programming/runsnakerun/)" 943 | ] 944 | } 945 | ], 946 | "metadata": { 947 | "kernelspec": { 948 | "display_name": "Python 3", 949 | "language": "python", 950 | "name": "python3" 951 | }, 952 | "language_info": { 953 | "codemirror_mode": { 954 | "name": "ipython", 955 | "version": 3 956 | }, 957 | "file_extension": ".py", 958 | "mimetype": "text/x-python", 959 | "name": "python", 960 | "nbconvert_exporter": "python", 961 | "pygments_lexer": "ipython3", 962 | "version": "3.6.1" 963 | } 964 | }, 965 | "nbformat": 4, 966 | "nbformat_minor": 2 967 | } 968 | -------------------------------------------------------------------------------- /2.7. 数学优化:找到函数的最优解.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 2, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "%matplotlib inline\n", 12 | "import numpy as np" 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": {}, 18 | "source": [ 19 | "> **作者**:\tGaël Varoquaux\n", 20 | "\n", 21 | "[数学优化](http://en.wikipedia.org/wiki/Mathematical_optimization)处理寻找一个函数的最小值(最大值或零)的问题。在这种情况下,这个函数被称为*成本函数*,或*目标函数*,或*能量*。\n", 22 | "\n", 23 | "这里,我们感兴趣的是使用[scipy.optimize](http://docs.scipy.org/doc/scipy/reference/optimize.html#scipy.optimize)来进行黑盒优化: 我们不依赖于我们优化的函数的算术表达式。注意这个表达式通常可以用于高效的、非黑盒优化。\n", 24 | "\n", 25 | "> 先决条件\n", 26 | "- Numpy, Scipy\n", 27 | "- matplotlib\n", 28 | "\n", 29 | "---\n", 30 | "\n", 31 | "**也可以看一下: 参考**\n", 32 | "\n", 33 | "数学优化是非常 ... 数学的。如果你需要性能,那么很有必要读一下这些书:\n", 34 | "- [Convex Optimization](http://www.stanford.edu/~boyd/cvxbook/) Boyd and Vandenberghe (pdf版线上免费)。\n", 35 | "- [Numerical Optimization](http://users.eecs.northwestern.edu/~nocedal/book/num-opt.html), Nocedal and Wright。 关于梯度下降方法的详细参考。\n", 36 | "- [Practical Methods of Optimization](http://www.amazon.com/gp/product/0471494631/ref=ox_sc_act_title_1?ie=UTF8&smid=ATVPDKIKX0DER) Fletcher: 擅长挥手解释。\n", 37 | "\n", 38 | "**章节内容**\n", 39 | "- 了解你的问题\n", 40 | " - 凸优化 VS 非凸优化\n", 41 | " - 平滑问题和非平滑问题\n", 42 | " - 嘈杂VS精确的成本函数\n", 43 | " - 限制\n", 44 | "- 不同最优化方法的回顾\n", 45 | " - 入门: 一维最优化\n", 46 | " - 基于梯度的方法\n", 47 | " - 牛顿和拟牛顿法\n", 48 | " - 较少梯度方法\n", 49 | " - 全局优化\n", 50 | "- 使用scipy优化的操作指南\n", 51 | " - 选择一个方法\n", 52 | " - 让你的优化器更快\n", 53 | " - 计算梯度\n", 54 | " - 虚拟练习\n", 55 | "- 特殊情境: 非线性最小二乘\n", 56 | " - 最小化向量函数的范数\n", 57 | " - 曲线拟合\n", 58 | "- 有限制的最优化\n", 59 | " - 箱边界\n", 60 | " - 通用限制\n", 61 | " \n", 62 | "## 2.7.1 了解你的问题\n", 63 | "\n", 64 | "每个问题都是不相同。了解你的问题使你可以选择正确的工具。\n", 65 | "\n", 66 | "---\n", 67 | "**问题的维数**\n", 68 | "\n", 69 | "优化问题的规模非常好的由问题的维数来决定,即,进行搜索的标量变量的数量。\n", 70 | "\n", 71 | "---\n", 72 | "\n", 73 | "### 2.7.1.1 凸优化 VS 非凸优化\n", 74 | "\n", 75 | "**凸函数**:\n", 76 | "- $f$ 在它的所有切线之上。\n", 77 | "- 相应的, 对于两个点point A, B, f(C) 在线段[f(A), f(B])]之下, 如果 A < C < B\n", 78 | "\n", 79 | "![](http://www.scipy-lectures.org/_images/plot_convex_1.png)\n", 80 | "\n", 81 | "**非凸函数**\n", 82 | "\n", 83 | "![](http://www.scipy-lectures.org/_images/plot_convex_2.png)\n", 84 | "\n", 85 | "**最优化凸函数简单。最优化非凸函数可能非常困难。**\n", 86 | "\n", 87 | "> **注意**: 可以证明对于一个凸函数局部最小值也是全局最小值。然后,从某种意义上说,最小值是惟一的。\n", 88 | "\n", 89 | "### 2.7.1.2 平滑和非平滑问题\n", 90 | "\n", 91 | "**平滑函数**:\n", 92 | "\n", 93 | "梯度无处不在,是一个连续函数\n", 94 | "\n", 95 | "![](http://www.scipy-lectures.org/_images/plot_smooth_1.png)\n", 96 | "\n", 97 | "**非平滑函数**:\n", 98 | "\n", 99 | "![](http://www.scipy-lectures.org/_images/plot_smooth_2.png)\n", 100 | "\n", 101 | "**优化平滑函数更简单一些** (在黑盒最优化的前提是对的,此外[线性编程](http://en.wikipedia.org/wiki/Linear_programming)是一个非常高效处理分段线性函数的例子)。\n", 102 | "\n", 103 | "### 2.7.1.3 嘈杂 VS 精确成本函数\n", 104 | "\n", 105 | "有噪音 (blue) 和无噪音 (green) 函数\n", 106 | "\n", 107 | "![](http://www.scipy-lectures.org/_images/plot_noisy_1.png)\n", 108 | "\n", 109 | "**噪音梯度**\n", 110 | "\n", 111 | "许多优化方法都依赖于目标函数的梯度。如果没有给出梯度函数,会从数值上计算他们,会产生误差。在这种情况下,即使目标函数没有噪音,基于梯度的最优化也可能是噪音最优化。\n", 112 | "\n", 113 | "### 2.7.1.4 限制\n", 114 | "\n", 115 | "基于限制的最优化\n", 116 | "\n", 117 | "这里是:\n", 118 | "\n", 119 | "$-1 < x_1 < 1$\n", 120 | "\n", 121 | "$-1 < x_2 < 1$\n", 122 | "\n", 123 | "![](http://www.scipy-lectures.org/_images/plot_constraints_1.png)\n", 124 | "\n", 125 | "## 2.7.2 不同最优化方法的回顾\n", 126 | "\n", 127 | "### 2.7.2.1 入门: 一维最优化\n", 128 | "\n", 129 | "使用[scipy.optimize.brent()](http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.brent.html#scipy.optimize.brent) 来最小化一维函数。它混合抛物线近似与区间策略。\n", 130 | "\n", 131 | "**二元函数的Brent方法**: 在3次迭代后收敛, 因为,稍后二元近似精确了。\n", 132 | "\n", 133 | "![](http://www.scipy-lectures.org/_images/plot_1d_optim_1.png)\n", 134 | "\n", 135 | "![](http://www.scipy-lectures.org/_images/plot_1d_optim_2.png)\n", 136 | "\n", 137 | "**非凸函数的Brent方法**: 注意最优化方法避免了局部最小值其实是因为运气。\n", 138 | "\n", 139 | "![](http://www.scipy-lectures.org/_images/plot_1d_optim_3.png)\n", 140 | "\n", 141 | "![](http://www.scipy-lectures.org/_images/plot_1d_optim_4.png)" 142 | ] 143 | }, 144 | { 145 | "cell_type": "code", 146 | "execution_count": 4, 147 | "metadata": { 148 | "collapsed": false 149 | }, 150 | "outputs": [ 151 | { 152 | "data": { 153 | "text/plain": [ 154 | "0.6999999997839409" 155 | ] 156 | }, 157 | "execution_count": 4, 158 | "metadata": {}, 159 | "output_type": "execute_result" 160 | } 161 | ], 162 | "source": [ 163 | "from scipy import optimize\n", 164 | "def f(x):\n", 165 | " return -np.exp(-(x - .7)**2)\n", 166 | "x_min = optimize.brent(f) # 实际上在9次迭代后收敛!\n", 167 | "x_min " 168 | ] 169 | }, 170 | { 171 | "cell_type": "code", 172 | "execution_count": 4, 173 | "metadata": { 174 | "collapsed": false 175 | }, 176 | "outputs": [ 177 | { 178 | "data": { 179 | "text/plain": [ 180 | "-2.160590595323697e-10" 181 | ] 182 | }, 183 | "execution_count": 4, 184 | "metadata": {}, 185 | "output_type": "execute_result" 186 | } 187 | ], 188 | "source": [ 189 | "x_min - .7 " 190 | ] 191 | }, 192 | { 193 | "cell_type": "markdown", 194 | "metadata": {}, 195 | "source": [ 196 | "> **注意**: Brent方法也可以用于*限制区间最优化*使用[scipy.optimize.fminbound()](http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fminbound.html#scipy.optimize.fminbound)\n", 197 | "\n", 198 | "> **注意**: 在scipy 0.11中, [scipy.optimize.minimize_scalar()](http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize_scalar.html#scipy.optimize.minimize_scalar) 给出了一个一维标量最优化的通用接口。\n", 199 | "\n", 200 | "### 2.7.2.2 基于梯度的方法\n", 201 | "\n", 202 | "#### 2.7.2.2.1 关于梯度下降的一些直觉\n", 203 | "\n", 204 | "这里我们关注**直觉**,不是代码。代码在后面。\n", 205 | "\n", 206 | "从根本上说,梯度下降在于在梯度方向上前进小步,即最陡峭梯度的方向。\n", 207 | "\n", 208 | "**固定步数梯度下降**\n", 209 | "\n", 210 | "**状况良好的二元函数。**\n", 211 | "\n", 212 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_0.png)\n", 213 | "\n", 214 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_100.png)\n", 215 | "\n", 216 | "**状况糟糕的二元函数。**\n", 217 | "\n", 218 | "状况糟糕问题的梯度下降算法的核心问题是梯度并不会指向最低点。\n", 219 | "\n", 220 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_2.png)\n", 221 | "\n", 222 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_102.png)\n", 223 | "\n", 224 | "我们可以看到非常各向异性 (状况糟糕) 函数非常难优化。\n", 225 | "\n", 226 | "---\n", 227 | "\n", 228 | "**带回家的信息**: 条件数和预条件化\n", 229 | "\n", 230 | "如果你知道变量的自然刻度,预刻度他们以便他们的行为相似。这与[预条件化](https://en.wikipedia.org/wiki/Preconditioner)相关。\n", 231 | "\n", 232 | "---\n", 233 | "\n", 234 | "并且,很明显采用大步幅是有优势的。这在梯度下降代码中使用[直线搜索](https://en.wikipedia.org/wiki/Line_search)。\n", 235 | "\n", 236 | "**适应步数梯度下降**\n", 237 | "\n", 238 | "\n", 239 | "状况良好的二元函数。\n", 240 | "\n", 241 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_1.png)\n", 242 | "\n", 243 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_101.png)\n", 244 | "\n", 245 | "状况糟糕的二元函数。\n", 246 | "\n", 247 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_3.png)\n", 248 | "\n", 249 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_103.png)\n", 250 | "\n", 251 | "状况糟糕的非二元函数。\n", 252 | "\n", 253 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_4.png)\n", 254 | "\n", 255 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_104.png)\n", 256 | "\n", 257 | "状况糟糕的极端非二元函数。\n", 258 | "\n", 259 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_5.png)\n", 260 | "\n", 261 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_105.png)\n", 262 | "\n", 263 | "函数看起来越像二元函数 (椭圆半圆边框线), 最优化越简单。\n", 264 | "\n", 265 | "#### 2.7.2.2.2 共轭梯度下降\n", 266 | "\n", 267 | "上面的梯度下降算法是玩具不会被用于真实的问题。\n", 268 | "\n", 269 | "正如从上面例子中看到的,简单梯度下降算法的一个问题是,它试着摇摆穿越峡谷,每次跟随梯度的方法,以便穿越峡谷。共轭梯度通过添加*摩擦力*项来解决这个问题: 每一步依赖于前两个值的梯度然后急转弯减少了。\n", 270 | "\n", 271 | "**共轭梯度下降**\n", 272 | "\n", 273 | "状况糟糕的非二元函数。\n", 274 | "\n", 275 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_6.png)\n", 276 | "\n", 277 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_106.png)\n", 278 | "\n", 279 | "状况糟糕的极端非二元函数。\n", 280 | "\n", 281 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_7.png)\n", 282 | "\n", 283 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_107.png)\n", 284 | "\n", 285 | "在scipy中基于共轭梯度下降方法名称带有‘cg’。最小化函数的简单共轭梯度下降方法是[scipy.optimize.fmin_cg()](http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fmin_cg.html#scipy.optimize.fmin_cg):\n" 286 | ] 287 | }, 288 | { 289 | "cell_type": "code", 290 | "execution_count": 5, 291 | "metadata": { 292 | "collapsed": false 293 | }, 294 | "outputs": [ 295 | { 296 | "name": "stdout", 297 | "output_type": "stream", 298 | "text": [ 299 | "Optimization terminated successfully.\n", 300 | " Current function value: 0.000000\n", 301 | " Iterations: 13\n", 302 | " Function evaluations: 120\n", 303 | " Gradient evaluations: 30\n" 304 | ] 305 | }, 306 | { 307 | "data": { 308 | "text/plain": [ 309 | "array([ 0.99998968, 0.99997855])" 310 | ] 311 | }, 312 | "execution_count": 5, 313 | "metadata": {}, 314 | "output_type": "execute_result" 315 | } 316 | ], 317 | "source": [ 318 | "def f(x): # The rosenbrock函数\n", 319 | " return .5*(1 - x[0])**2 + (x[1] - x[0]**2)**2\n", 320 | "optimize.fmin_cg(f, [2, 2]) " 321 | ] 322 | }, 323 | { 324 | "cell_type": "markdown", 325 | "metadata": {}, 326 | "source": [ 327 | "这些方法需要函数的梯度。方法可以计算梯度,但是如果传递了梯度性能将更好:" 328 | ] 329 | }, 330 | { 331 | "cell_type": "code", 332 | "execution_count": 6, 333 | "metadata": { 334 | "collapsed": false 335 | }, 336 | "outputs": [ 337 | { 338 | "name": "stdout", 339 | "output_type": "stream", 340 | "text": [ 341 | "Optimization terminated successfully.\n", 342 | " Current function value: 0.000000\n", 343 | " Iterations: 13\n", 344 | " Function evaluations: 30\n", 345 | " Gradient evaluations: 30\n" 346 | ] 347 | }, 348 | { 349 | "data": { 350 | "text/plain": [ 351 | "array([ 0.99999199, 0.99998336])" 352 | ] 353 | }, 354 | "execution_count": 6, 355 | "metadata": {}, 356 | "output_type": "execute_result" 357 | } 358 | ], 359 | "source": [ 360 | "def fprime(x):\n", 361 | " return np.array((-2*.5*(1 - x[0]) - 4*x[0]*(x[1] - x[0]**2), 2*(x[1] - x[0]**2)))\n", 362 | "optimize.fmin_cg(f, [2, 2], fprime=fprime) " 363 | ] 364 | }, 365 | { 366 | "cell_type": "markdown", 367 | "metadata": {}, 368 | "source": [ 369 | "注意函数只会评估30次,相对的没有梯度是120次。\n", 370 | "\n", 371 | "### 2.7.2.3 牛顿和拟牛顿法\n", 372 | "\n", 373 | "#### 2.7.2.3.1 牛顿法: 使用Hessian (二阶微分)\n", 374 | "\n", 375 | "[牛顿法](http://en.wikipedia.org/wiki/Newton%27s_method_in_optimization)使用局部二元近似来计算跳跃的方向。为了这个目的,他们依赖于函数的前两个导数*梯度*和[Hessian](http://en.wikipedia.org/wiki/Hessian_matrix)。\n", 376 | "\n", 377 | "**状况糟糕的二元函数:**\n", 378 | "\n", 379 | "注意,因为二元近似是精确的,牛顿法是非常快的。\n", 380 | "\n", 381 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_8.png)\n", 382 | "\n", 383 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_108.png)\n", 384 | "\n", 385 | "**状况糟糕的非二元函数:**\n", 386 | "\n", 387 | "这里我们最优化高斯分布,通常在它的二元近似的下面。因此,牛顿法超调量并且导致震荡。\n", 388 | "\n", 389 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_9.png)\n", 390 | "\n", 391 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_109.png)\n", 392 | "\n", 393 | "**状况糟糕的极端非二元函数:**\n", 394 | "\n", 395 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_10.png)\n", 396 | "\n", 397 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_110.png)\n", 398 | "\n", 399 | "在scipy中, 最优化的牛顿法在[scipy.optimize.fmin_ncg()](http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fmin_ncg.html#scipy.optimize.fmin_ncg)实现 (cg这里是指一个内部操作的事实,Hessian翻转, 使用共轭梯度来进行)。[scipy.optimize.fmin_tnc()](http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fmin_tnc.html#scipy.optimize.fmin_tnc) 可以被用于限制问题,尽管没有那么多用途:" 400 | ] 401 | }, 402 | { 403 | "cell_type": "code", 404 | "execution_count": 7, 405 | "metadata": { 406 | "collapsed": false 407 | }, 408 | "outputs": [ 409 | { 410 | "name": "stdout", 411 | "output_type": "stream", 412 | "text": [ 413 | "Optimization terminated successfully.\n", 414 | " Current function value: 0.000000\n", 415 | " Iterations: 9\n", 416 | " Function evaluations: 11\n", 417 | " Gradient evaluations: 51\n", 418 | " Hessian evaluations: 0\n" 419 | ] 420 | }, 421 | { 422 | "data": { 423 | "text/plain": [ 424 | "array([ 1., 1.])" 425 | ] 426 | }, 427 | "execution_count": 7, 428 | "metadata": {}, 429 | "output_type": "execute_result" 430 | } 431 | ], 432 | "source": [ 433 | "def f(x): # rosenbrock函数\n", 434 | " return .5*(1 - x[0])**2 + (x[1] - x[0]**2)**2\n", 435 | "def fprime(x):\n", 436 | " return np.array((-2*.5*(1 - x[0]) - 4*x[0]*(x[1] - x[0]**2), 2*(x[1] - x[0]**2)))\n", 437 | "optimize.fmin_ncg(f, [2, 2], fprime=fprime) " 438 | ] 439 | }, 440 | { 441 | "cell_type": "markdown", 442 | "metadata": {}, 443 | "source": [ 444 | "注意与共轭梯度(上面的)相比,牛顿法需要较少的函数评估,更多的梯度评估,因为它使用它近似Hessian。让我们计算Hessian并将它传给算法:" 445 | ] 446 | }, 447 | { 448 | "cell_type": "code", 449 | "execution_count": 7, 450 | "metadata": { 451 | "collapsed": false 452 | }, 453 | "outputs": [ 454 | { 455 | "name": "stdout", 456 | "output_type": "stream", 457 | "text": [ 458 | "Optimization terminated successfully.\n", 459 | " Current function value: 0.000000\n", 460 | " Iterations: 9\n", 461 | " Function evaluations: 11\n", 462 | " Gradient evaluations: 19\n", 463 | " Hessian evaluations: 9\n" 464 | ] 465 | }, 466 | { 467 | "data": { 468 | "text/plain": [ 469 | "array([ 1., 1.])" 470 | ] 471 | }, 472 | "execution_count": 7, 473 | "metadata": {}, 474 | "output_type": "execute_result" 475 | } 476 | ], 477 | "source": [ 478 | "def hessian(x): # Computed with sympy\n", 479 | " return np.array(((1 - 4*x[1] + 12*x[0]**2, -4*x[0]), (-4*x[0], 2)))\n", 480 | "optimize.fmin_ncg(f, [2, 2], fprime=fprime, fhess=hessian) " 481 | ] 482 | }, 483 | { 484 | "cell_type": "markdown", 485 | "metadata": {}, 486 | "source": [ 487 | "> **注意**:在超高维,Hessian的翻转代价高昂并且不稳定 (大规模 > 250)。\n", 488 | "\n", 489 | "> **注意**:牛顿最优化算法不应该与基于相同原理的牛顿根发现法相混淆,[scipy.optimize.newton()](http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.newton.html#scipy.optimize.newton)。\n", 490 | "\n", 491 | "#### 2.7.2.3.2 拟牛顿方法: 进行着近似Hessian\n", 492 | "\n", 493 | "**BFGS**: BFGS (Broyden-Fletcher-Goldfarb-Shanno算法) 改进了每一步对Hessian的近似。\n", 494 | "\n", 495 | "**状况糟糕的二元函数:**\n", 496 | "\n", 497 | "在准确的二元函数中, BFGS并不像牛顿法那么快,但是还是很快。\n", 498 | "\n", 499 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_11.png)\n", 500 | "\n", 501 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_111.png)\n", 502 | "\n", 503 | "**状况糟糕的非二元函数:**\n", 504 | "\n", 505 | "这种情况下BFGS比牛顿好, 因为它的曲度经验估计比Hessian给出的好。\n", 506 | "\n", 507 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_12.png)\n", 508 | "\n", 509 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_112.png)\n", 510 | "\n", 511 | "**状况糟糕的极端非二元函数:**\n", 512 | "\n", 513 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_13.png)\n", 514 | "\n", 515 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_113.png)" 516 | ] 517 | }, 518 | { 519 | "cell_type": "code", 520 | "execution_count": 9, 521 | "metadata": { 522 | "collapsed": false 523 | }, 524 | "outputs": [ 525 | { 526 | "name": "stdout", 527 | "output_type": "stream", 528 | "text": [ 529 | "Optimization terminated successfully.\n", 530 | " Current function value: 0.000000\n", 531 | " Iterations: 16\n", 532 | " Function evaluations: 24\n", 533 | " Gradient evaluations: 24\n" 534 | ] 535 | }, 536 | { 537 | "data": { 538 | "text/plain": [ 539 | "array([ 1.00000017, 1.00000026])" 540 | ] 541 | }, 542 | "execution_count": 9, 543 | "metadata": {}, 544 | "output_type": "execute_result" 545 | } 546 | ], 547 | "source": [ 548 | "def f(x): # rosenbrock函数\n", 549 | " return .5*(1 - x[0])**2 + (x[1] - x[0]**2)**2\n", 550 | "def fprime(x):\n", 551 | " return np.array((-2*.5*(1 - x[0]) - 4*x[0]*(x[1] - x[0]**2), 2*(x[1] - x[0]**2)))\n", 552 | "optimize.fmin_bfgs(f, [2, 2], fprime=fprime)" 553 | ] 554 | }, 555 | { 556 | "cell_type": "markdown", 557 | "metadata": {}, 558 | "source": [ 559 | "**L-BFGS**: 限制内存的BFGS介于BFGS和共轭梯度之间: 在非常高的维度 (> 250) 计算和翻转的Hessian矩阵的成本非常高。L-BFGS保留了低秩的版本。此外,scipy版本, [scipy.optimize.fmin_l_bfgs_b()](http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fmin_l_bfgs_b.html#scipy.optimize.fmin_l_bfgs_b), 包含箱边界:" 560 | ] 561 | }, 562 | { 563 | "cell_type": "code", 564 | "execution_count": 8, 565 | "metadata": { 566 | "collapsed": false 567 | }, 568 | "outputs": [ 569 | { 570 | "data": { 571 | "text/plain": [ 572 | "(array([ 1.00000005, 1.00000009]),\n", 573 | " 1.4417677473011859e-15,\n", 574 | " {'funcalls': 17,\n", 575 | " 'grad': array([ 1.02331202e-07, -2.59299369e-08]),\n", 576 | " 'nit': 16,\n", 577 | " 'task': 'CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL',\n", 578 | " 'warnflag': 0})" 579 | ] 580 | }, 581 | "execution_count": 8, 582 | "metadata": {}, 583 | "output_type": "execute_result" 584 | } 585 | ], 586 | "source": [ 587 | "def f(x): # rosenbrock函数\n", 588 | " return .5*(1 - x[0])**2 + (x[1] - x[0]**2)**2\n", 589 | "def fprime(x):\n", 590 | " return np.array((-2*.5*(1 - x[0]) - 4*x[0]*(x[1] - x[0]**2), 2*(x[1] - x[0]**2)))\n", 591 | "optimize.fmin_l_bfgs_b(f, [2, 2], fprime=fprime) " 592 | ] 593 | }, 594 | { 595 | "cell_type": "markdown", 596 | "metadata": {}, 597 | "source": [ 598 | "> **注意**:如果你不为L-BFGS求解器制定梯度,你需要添加approx_grad=1" 599 | ] 600 | }, 601 | { 602 | "cell_type": "markdown", 603 | "metadata": {}, 604 | "source": [ 605 | "### 2.7.2.4 较少梯度方法\n", 606 | "\n", 607 | "#### 2.7.2.4.1 打靶法: Powell算法\n", 608 | "\n", 609 | "接近梯度方法\n", 610 | "\n", 611 | "**状态糟糕的二元函数:**\n", 612 | "\n", 613 | "Powell法对低维局部糟糕状况并不很敏感\n", 614 | "\n", 615 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_14.png)\n", 616 | "\n", 617 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_114.png)\n", 618 | "\n", 619 | "**状况糟糕的极端非二元函数:**\n", 620 | "\n", 621 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_16.png)\n", 622 | "\n", 623 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_116.png)\n", 624 | "\n", 625 | "#### 2.7.2.4.2 单纯形法: Nelder-Mead\n", 626 | "\n", 627 | "Nelder-Mead算法是对高维空间的对立方法的归纳。这个算法通过改进[单纯形](http://en.wikipedia.org/wiki/Simplex)来工作,高维空间间隔和三角形的归纳,包裹最小值。\n", 628 | "\n", 629 | "**长处**: 对噪音很强壮,他不依赖于计算梯度。因此,它可以在局部光滑的函数上工作,比如实验数据点,只要他显示了一个大规模的钟形行为。但是,它在光滑、非噪音函数上比基于梯度的方法慢。\n", 630 | "\n", 631 | "**状况糟糕的非二元函数:**\n", 632 | "\n", 633 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_17.png)\n", 634 | "\n", 635 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_117.png)\n", 636 | "\n", 637 | "**状况糟糕的极端非二元函数:**\n", 638 | "\n", 639 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_18.png)\n", 640 | "\n", 641 | "![](http://www.scipy-lectures.org/_images/plot_gradient_descent_118.png)\n", 642 | "\n", 643 | "在scipy中, [scipy.optimize.fmin()](http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fmin.html#scipy.optimize.fmin) 实现了Nelder-Mead法:" 644 | ] 645 | }, 646 | { 647 | "cell_type": "code", 648 | "execution_count": 11, 649 | "metadata": { 650 | "collapsed": false 651 | }, 652 | "outputs": [ 653 | { 654 | "name": "stdout", 655 | "output_type": "stream", 656 | "text": [ 657 | "Optimization terminated successfully.\n", 658 | " Current function value: 0.000000\n", 659 | " Iterations: 46\n", 660 | " Function evaluations: 91\n" 661 | ] 662 | }, 663 | { 664 | "data": { 665 | "text/plain": [ 666 | "array([ 0.99998568, 0.99996682])" 667 | ] 668 | }, 669 | "execution_count": 11, 670 | "metadata": {}, 671 | "output_type": "execute_result" 672 | } 673 | ], 674 | "source": [ 675 | "def f(x): # rosenbrock函数\n", 676 | " return .5*(1 - x[0])**2 + (x[1] - x[0]**2)**2\n", 677 | "optimize.fmin(f, [2, 2])" 678 | ] 679 | }, 680 | { 681 | "cell_type": "markdown", 682 | "metadata": {}, 683 | "source": [ 684 | "### 2.7.2.5 全局最优化算法\n", 685 | "\n", 686 | "如果你的问题不允许惟一的局部最低点(很难测试除非是凸函数),如果你没有先前知识来让优化起点接近答案,你可能需要全局最优化算法。\n", 687 | "\n", 688 | "#### 2.7.2.5.1 暴力: 网格搜索\n", 689 | "\n", 690 | "[scipy.optimize.brute()](http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.brute.html#scipy.optimize.brute)在 函数网格内来评价函数,根据最小值返回参数。参数由[numpy.mgrid](http://docs.scipy.org/doc/numpy/reference/generated/numpy.mgrid.html#numpy.mgrid)给出的范围来指定。默认情况下,每个方向进行20步:" 691 | ] 692 | }, 693 | { 694 | "cell_type": "code", 695 | "execution_count": 4, 696 | "metadata": { 697 | "collapsed": false 698 | }, 699 | "outputs": [ 700 | { 701 | "data": { 702 | "text/plain": [ 703 | "array([ 1.00001462, 1.00001547])" 704 | ] 705 | }, 706 | "execution_count": 4, 707 | "metadata": {}, 708 | "output_type": "execute_result" 709 | } 710 | ], 711 | "source": [ 712 | "def f(x): # rosenbrock函数\n", 713 | " return .5*(1 - x[0])**2 + (x[1] - x[0]**2)**2\n", 714 | "optimize.brute(f, ((-1, 2), (-1, 2)))" 715 | ] 716 | }, 717 | { 718 | "cell_type": "markdown", 719 | "metadata": {}, 720 | "source": [ 721 | "## 2.7.3 使用scipy优化的现实指南\n", 722 | "\n", 723 | "### 2.7.3.1 选择一个方法\n", 724 | "\n", 725 | "![](http://www.scipy-lectures.org/_images/plot_compare_optimizers_1.png)\n", 726 | "\n", 727 | "---\n", 728 | "\n", 729 | "**没有关于梯度的知识:**\n", 730 | " \t\n", 731 | "- 一般来说,倾向于BFGS ([scipy.optimize.fmin_bfgs()](http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fmin_bfgs.html#scipy.optimize.fmin_bfgs)) 或 L-BFGS ([scipy.optimize.fmin_l_bfgs_b()]()), 即使你有大概的数值梯度\n", 732 | "- 在状况良好的问题上,Powell ([scipy.optimize.fmin_powell()]()) 以及 Nelder-Mead ([scipy.optimize.fmin()](http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fmin.html#scipy.optimize.fmin)), 都是在高维上效果良好的梯度自有的方法,但是 ,他们无法支持状况糟糕的问题。\n", 733 | "\n", 734 | "---\n", 735 | "\n", 736 | "---\n", 737 | "\n", 738 | "**有关于梯度的知识:**\n", 739 | " \t\n", 740 | "- BFGS ([scipy.optimize.fmin_bfgs()](http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fmin_bfgs.html#scipy.optimize.fmin_bfgs)) 或 L-BFGS ([scipy.optimize.fmin_l_bfgs_b()](http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fmin_l_bfgs_b.html#scipy.optimize.fmin_l_bfgs_b))。\n", 741 | "- BFGS的计算开支要大于L-BFGS, 它自身也比共轭梯度法开销大。另一方面,BFGS通常比CG(共轭梯度法)需要更少函数评估。因此,共轭梯度法在优化计算量较少的函数时比BFGS更好。\n", 742 | "\n", 743 | "---\n", 744 | "\n", 745 | "---\n", 746 | "**带有Hessian**:\n", 747 | "\n", 748 | "- 如果你可以计算Hessian, 推荐牛顿法 ([scipy.optimize.fmin_ncg()](http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fmin_ncg.html#scipy.optimize.fmin_ncg))。\n", 749 | "\n", 750 | "**如果有噪音测量**:\n", 751 | " \t\n", 752 | "使用Nelder-Mead ([scipy.optimize.fmin()](http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fmin.html#scipy.optimize.fmin)) 或者 Powell ([scipy.optimize.fmin_powell()](http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fmin_powell.html#scipy.optimize.fmin_powell))。\n", 753 | "\n", 754 | "### 2.7.3.2 让优化器更快\n", 755 | "\n", 756 | "- 选择正确的方法 (见上面), 如果可以的话,计算梯度和Hessia。\n", 757 | "- 可能的时候使用[preconditionning](http://en.wikipedia.org/wiki/Preconditioner)。\n", 758 | "- 聪明的选择你的起点。例如,如果你正在运行许多相似的优化,那么在其他结果上软启动。\n", 759 | "- 如果你不需要准确,那么请放松并容忍\n", 760 | "\n", 761 | "### 2.7.3.3 计算梯度\n", 762 | "\n", 763 | "计算梯度甚至是Hessians的努力, 是枯燥的但是也是值得的。使用[Sympy](http://www.scipy-lectures.org/packages/sympy.html#sympy)来进行象征计算将非常方便。\n", 764 | "\n", 765 | "优化不能很好收敛的一个来源是计算梯度过程的人为错误。你可以用[scipy.optimize.check_grad()](http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.check_grad.html#scipy.optimize.check_grad)来检查一下梯度是否正确。它返回给出的梯度与计算的梯度之间差异的基准:" 766 | ] 767 | }, 768 | { 769 | "cell_type": "code", 770 | "execution_count": 9, 771 | "metadata": { 772 | "collapsed": false 773 | }, 774 | "outputs": [ 775 | { 776 | "data": { 777 | "text/plain": [ 778 | "2.384185791015625e-07" 779 | ] 780 | }, 781 | "execution_count": 9, 782 | "metadata": {}, 783 | "output_type": "execute_result" 784 | } 785 | ], 786 | "source": [ 787 | "optimize.check_grad(f, fprime, [2, 2])" 788 | ] 789 | }, 790 | { 791 | "cell_type": "markdown", 792 | "metadata": {}, 793 | "source": [ 794 | "也看一下[scipy.optimize.approx_fprime()](http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.approx_fprime.html#scipy.optimize.approx_fprime)找一下你的错误。\n", 795 | "#### 2.7.3.4 合成练习\n", 796 | "\n", 797 | "**练习: 简单的 (?) 二次函数**\n", 798 | "\n", 799 | "![](http://www.scipy-lectures.org/_images/plot_exercise_ill_conditioned_1.png)\n", 800 | "\n", 801 | "用K[0]作为起始点优化下列函数:" 802 | ] 803 | }, 804 | { 805 | "cell_type": "code", 806 | "execution_count": 2, 807 | "metadata": { 808 | "collapsed": false 809 | }, 810 | "outputs": [], 811 | "source": [ 812 | "np.random.seed(0)\n", 813 | "K = np.random.normal(size=(100, 100))\n", 814 | "\n", 815 | "def f(x):\n", 816 | " return np.sum((np.dot(K, x - 1))**2) + np.sum(x**2)**2" 817 | ] 818 | }, 819 | { 820 | "cell_type": "markdown", 821 | "metadata": {}, 822 | "source": [ 823 | "计时你的方法。找到最快的方法。为什么BFGS不好用了?\n", 824 | "\n", 825 | "**练习:局部扁平最小化**\n", 826 | "\n", 827 | "![](http://www.scipy-lectures.org/_images/plot_exercise_flat_minimum_0.png)\n", 828 | "\n", 829 | "![](http://www.scipy-lectures.org/_images/plot_exercise_flat_minimum_1.png)\n", 830 | "\n", 831 | "考虑一下函数$exp(-1/(.1*x^2 + y^2)$。这个函数在(0,0)存在一个最小值。从起点(1,1)开始,试着在$1e-8$达到这个最低点。\n", 832 | "\n", 833 | "## 2.7.4 特殊案例: 非线性最小二乘\n", 834 | "\n", 835 | "### 2.7.4.1 最小化向量函数的基准\n", 836 | "\n", 837 | "最小二乘法,向量函数基准值的最小化,有特定的结构可以用在[scipy.optimize.leastsq()](http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.leastsq.html#scipy.optimize.leastsq)中实现的[Levenberg–Marquardt 算法](https://en.wikipedia.org/wiki/Levenberg-Marquardt_algorithm)。\n", 838 | "\n", 839 | "让我们试一下最小化下面向量函数的基准:" 840 | ] 841 | }, 842 | { 843 | "cell_type": "code", 844 | "execution_count": 5, 845 | "metadata": { 846 | "collapsed": false 847 | }, 848 | "outputs": [ 849 | { 850 | "data": { 851 | "text/plain": [ 852 | "(array([ 0. , 0.11111111, 0.22222222, 0.33333333, 0.44444444,\n", 853 | " 0.55555556, 0.66666667, 0.77777778, 0.88888889, 1. ]), 2)" 854 | ] 855 | }, 856 | "execution_count": 5, 857 | "metadata": {}, 858 | "output_type": "execute_result" 859 | } 860 | ], 861 | "source": [ 862 | "def f(x):\n", 863 | " return np.arctan(x) - np.arctan(np.linspace(0, 1, len(x)))\n", 864 | "x0 = np.zeros(10)\n", 865 | "optimize.leastsq(f, x0)" 866 | ] 867 | }, 868 | { 869 | "cell_type": "markdown", 870 | "metadata": {}, 871 | "source": [ 872 | "这用了67次函数评估(用'full_output=1'试一下)。如果我们自己计算基准并且使用一个更好的通用优化器(BFGS)会怎么样:" 873 | ] 874 | }, 875 | { 876 | "cell_type": "code", 877 | "execution_count": 6, 878 | "metadata": { 879 | "collapsed": false 880 | }, 881 | "outputs": [ 882 | { 883 | "name": "stdout", 884 | "output_type": "stream", 885 | "text": [ 886 | "Optimization terminated successfully.\n", 887 | " Current function value: 0.000000\n", 888 | " Iterations: 11\n", 889 | " Function evaluations: 144\n", 890 | " Gradient evaluations: 12\n" 891 | ] 892 | }, 893 | { 894 | "data": { 895 | "text/plain": [ 896 | "array([ -7.44987291e-09, 1.11112265e-01, 2.22219893e-01,\n", 897 | " 3.33331914e-01, 4.44449794e-01, 5.55560493e-01,\n", 898 | " 6.66672149e-01, 7.77779758e-01, 8.88882036e-01,\n", 899 | " 1.00001026e+00])" 900 | ] 901 | }, 902 | "execution_count": 6, 903 | "metadata": {}, 904 | "output_type": "execute_result" 905 | } 906 | ], 907 | "source": [ 908 | "def g(x):\n", 909 | " return np.sum(f(x)**2)\n", 910 | "optimize.fmin_bfgs(g, x0) " 911 | ] 912 | }, 913 | { 914 | "cell_type": "markdown", 915 | "metadata": {}, 916 | "source": [ 917 | "BFGS需要更多的函数调用,并且给出了一个并不精确的结果。\n", 918 | "\n", 919 | "注意只有当输出向量的维度非常大,比需要优化的函数还要大,`leastsq`与BFGS相类比才是有趣的。\n", 920 | "\n", 921 | "如果函数是线性的,这是一个线性代数问题,应该用[scipy.linalg.lstsq()](http://docs.scipy.org/doc/scipy/reference/generated/scipy.linalg.lstsq.html#scipy.linalg.lstsq)解决。\n", 922 | "\n", 923 | "### 2.7.4.2 曲线拟合\n", 924 | "\n", 925 | "![](http://www.scipy-lectures.org/_images/plot_curve_fit_1.png)\n", 926 | "\n", 927 | "最小二乘问题通常出现在拟合数据的非线性拟合时。当我们自己构建优化问题时,scipy提供了这种目的的一个帮助函数: [scipy.optimize.curve_fit()](http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html#scipy.optimize.curve_fit):" 928 | ] 929 | }, 930 | { 931 | "cell_type": "code", 932 | "execution_count": 7, 933 | "metadata": { 934 | "collapsed": false 935 | }, 936 | "outputs": [ 937 | { 938 | "data": { 939 | "text/plain": [ 940 | "(array([ 1.50600889, 0.98754323]), array([[ 0.00030286, -0.00045233],\n", 941 | " [-0.00045233, 0.00098838]]))" 942 | ] 943 | }, 944 | "execution_count": 7, 945 | "metadata": {}, 946 | "output_type": "execute_result" 947 | } 948 | ], 949 | "source": [ 950 | "def f(t, omega, phi):\n", 951 | " return np.cos(omega * t + phi)\n", 952 | "x = np.linspace(0, 3, 50)\n", 953 | "y = f(x, 1.5, 1) + .1*np.random.normal(size=50)\n", 954 | "optimize.curve_fit(f, x, y)" 955 | ] 956 | }, 957 | { 958 | "cell_type": "markdown", 959 | "metadata": {}, 960 | "source": [ 961 | "**练习**\n", 962 | "\n", 963 | "用omega = 3来进行相同的练习。困难是什么?\n", 964 | "\n", 965 | "## 2.7.5 有限制条件的优化\n", 966 | "\n", 967 | "### 2.7.5.1 箱边界\n", 968 | "\n", 969 | "![](http://www.scipy-lectures.org/_images/plot_constraints_2.png)\n", 970 | "\n", 971 | "箱边界是指限制优化的每个函数。注意一些最初不是写成箱边界的问题可以通过改变变量重写。\n", 972 | "\n", 973 | "- [scipy.optimize.fminbound()](http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fminbound.html#scipy.optimize.fminbound)进行一维优化\n", 974 | "- [scipy.optimize.fmin_l_bfgs_b()](http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fmin_l_bfgs_b.html#scipy.optimize.fmin_l_bfgs_b)带有边界限制的quasi-Newton方法:" 975 | ] 976 | }, 977 | { 978 | "cell_type": "code", 979 | "execution_count": 8, 980 | "metadata": { 981 | "collapsed": false 982 | }, 983 | "outputs": [ 984 | { 985 | "data": { 986 | "text/plain": [ 987 | "(array([ 1.5, 1.5]),\n", 988 | " 1.5811388300841898,\n", 989 | " {'funcalls': 12,\n", 990 | " 'grad': array([-0.94868331, -0.31622778]),\n", 991 | " 'nit': 2,\n", 992 | " 'task': 'CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL',\n", 993 | " 'warnflag': 0})" 994 | ] 995 | }, 996 | "execution_count": 8, 997 | "metadata": {}, 998 | "output_type": "execute_result" 999 | } 1000 | ], 1001 | "source": [ 1002 | "def f(x):\n", 1003 | " return np.sqrt((x[0] - 3)**2 + (x[1] - 2)**2)\n", 1004 | "optimize.fmin_l_bfgs_b(f, np.array([0, 0]), approx_grad=1, bounds=((-1.5, 1.5), (-1.5, 1.5))) " 1005 | ] 1006 | }, 1007 | { 1008 | "cell_type": "markdown", 1009 | "metadata": {}, 1010 | "source": [ 1011 | "### 2.7.5.2 通用限制\n", 1012 | "\n", 1013 | "相等和不相等限制特定函数: f(x) = 0 and g(x)< 0。\n", 1014 | "\n", 1015 | "![](http://www.scipy-lectures.org/_images/plot_non_bounds_constraints_1.png)\n", 1016 | "\n", 1017 | "- [scipy.optimize.fmin_slsqp()](http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fmin_slsqp.html#scipy.optimize.fmin_slsqp) 序列最小二乘程序: 相等和不相等限制:" 1018 | ] 1019 | }, 1020 | { 1021 | "cell_type": "code", 1022 | "execution_count": 10, 1023 | "metadata": { 1024 | "collapsed": false 1025 | }, 1026 | "outputs": [ 1027 | { 1028 | "name": "stdout", 1029 | "output_type": "stream", 1030 | "text": [ 1031 | "Optimization terminated successfully. (Exit mode 0)\n", 1032 | " Current function value: 2.47487373504\n", 1033 | " Iterations: 5\n", 1034 | " Function evaluations: 20\n", 1035 | " Gradient evaluations: 5\n" 1036 | ] 1037 | }, 1038 | { 1039 | "data": { 1040 | "text/plain": [ 1041 | "array([ 1.25004696, 0.24995304])" 1042 | ] 1043 | }, 1044 | "execution_count": 10, 1045 | "metadata": {}, 1046 | "output_type": "execute_result" 1047 | } 1048 | ], 1049 | "source": [ 1050 | "def f(x):\n", 1051 | " return np.sqrt((x[0] - 3)**2 + (x[1] - 2)**2)\n", 1052 | "\n", 1053 | "def constraint(x):\n", 1054 | " return np.atleast_1d(1.5 - np.sum(np.abs(x)))\n", 1055 | "\n", 1056 | "optimize.fmin_slsqp(f, np.array([0, 0]), ieqcons=[constraint, ])" 1057 | ] 1058 | }, 1059 | { 1060 | "cell_type": "markdown", 1061 | "metadata": {}, 1062 | "source": [ 1063 | "- [scipy.optimize.fmin_cobyla()](http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fmin_cobyla.html#scipy.optimize.fmin_cobyla)通过线性估计的限定优化:只有不相等限制:" 1064 | ] 1065 | }, 1066 | { 1067 | "cell_type": "code", 1068 | "execution_count": 11, 1069 | "metadata": { 1070 | "collapsed": false 1071 | }, 1072 | "outputs": [ 1073 | { 1074 | "data": { 1075 | "text/plain": [ 1076 | "array([ 1.25009622, 0.24990378])" 1077 | ] 1078 | }, 1079 | "execution_count": 11, 1080 | "metadata": {}, 1081 | "output_type": "execute_result" 1082 | } 1083 | ], 1084 | "source": [ 1085 | "optimize.fmin_cobyla(f, np.array([0, 0]), cons=constraint)" 1086 | ] 1087 | }, 1088 | { 1089 | "cell_type": "markdown", 1090 | "metadata": {}, 1091 | "source": [ 1092 | "上面这个问题在统计中被称为[Lasso](http://en.wikipedia.org/wiki/Lasso_(statistics)#LASSO_method)问题, 有许多解决它的高效方法 (比如在[scikit-learn](http://scikit-learn.org/)中)。一般来说,当特定求解器存在时不需要使用通用求解器。\n", 1093 | "\n", 1094 | "**拉格朗日乘子法**\n", 1095 | "\n", 1096 | "如果你有足够的数学知识,许多限定优化问题可以被转化为非限定性优化问题,使用被称为拉格朗日乘子法的数学技巧。" 1097 | ] 1098 | } 1099 | ], 1100 | "metadata": { 1101 | "kernelspec": { 1102 | "display_name": "Python 2", 1103 | "language": "python", 1104 | "name": "python2" 1105 | }, 1106 | "language_info": { 1107 | "codemirror_mode": { 1108 | "name": "ipython", 1109 | "version": 2 1110 | }, 1111 | "file_extension": ".py", 1112 | "mimetype": "text/x-python", 1113 | "name": "python", 1114 | "nbconvert_exporter": "python", 1115 | "pygments_lexer": "ipython2", 1116 | "version": "2.7.11" 1117 | } 1118 | }, 1119 | "nbformat": 4, 1120 | "nbformat_minor": 0 1121 | } 1122 | -------------------------------------------------------------------------------- /3.2. Sympy:Python中的符号数学.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": false 7 | }, 8 | "source": [ 9 | ">**作者** : Fabian Pedregosa\n", 10 | "\n", 11 | "---\n", 12 | "**目的**\n", 13 | "- 从任意的精度评估表达式。\n", 14 | "- 在符号表达式上进行代数运算。\n", 15 | "- 用符号表达式进行基本的微积分任务 (极限、微分法和积分法)。\n", 16 | "- 求解多项式和超越方程。\n", 17 | "- 求解一些微分方程。\n", 18 | "\n", 19 | "---\n", 20 | "\n", 21 | "为什么是SymPy? SymPy是符号数学的Python库。它的目的是成为Mathematica或Maple等系统的替代品,同时让代码尽可能简单并且可扩展。SymPy完全是用Python写的,并不需要外部的库。\n", 22 | "\n", 23 | "Sympy文档及库安装见http://www.sympy.org/\n", 24 | "\n", 25 | "---\n", 26 | "**章节内容**\n", 27 | "- SymPy第一步\n", 28 | " - 使用SymPy作为计算器\n", 29 | " - 练习\n", 30 | " - 符号\n", 31 | "- 代数运算\n", 32 | " - 展开\n", 33 | " - 化简\n", 34 | "- 微积分\n", 35 | " - 极限\n", 36 | " - 微分法\n", 37 | " - 序列扩展\n", 38 | " - 积分法\n", 39 | " - 练习\n", 40 | "- 方程求解\n", 41 | " - 练习\n", 42 | "- 线性代数\n", 43 | " - 矩阵\n", 44 | " - 微分方程\n", 45 | "\n", 46 | "---\n", 47 | "\n", 48 | "## 3.2.1 SymPy第一步\n", 49 | "\n", 50 | "### 3.2.1.1 使用SymPy作为计算器\n", 51 | "\n", 52 | "SymPy定义了三种数字类型:实数、有理数和整数。\n", 53 | "\n", 54 | "有理数类将有理数表征为两个整数对: 分子和分母,因此Rational(1,2)代表1/2, Rational(5,2)代表5/2等等:" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": 2, 60 | "metadata": { 61 | "collapsed": false 62 | }, 63 | "outputs": [], 64 | "source": [ 65 | "from sympy import *\n", 66 | "a = Rational(1,2)" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": 2, 72 | "metadata": { 73 | "collapsed": false 74 | }, 75 | "outputs": [ 76 | { 77 | "data": { 78 | "text/plain": [ 79 | "1/2" 80 | ] 81 | }, 82 | "execution_count": 2, 83 | "metadata": {}, 84 | "output_type": "execute_result" 85 | } 86 | ], 87 | "source": [ 88 | "a" 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": 3, 94 | "metadata": { 95 | "collapsed": false 96 | }, 97 | "outputs": [ 98 | { 99 | "data": { 100 | "text/plain": [ 101 | "1" 102 | ] 103 | }, 104 | "execution_count": 3, 105 | "metadata": {}, 106 | "output_type": "execute_result" 107 | } 108 | ], 109 | "source": [ 110 | "a*2" 111 | ] 112 | }, 113 | { 114 | "cell_type": "markdown", 115 | "metadata": {}, 116 | "source": [ 117 | "SymPy在底层使用mpmath, 这使它可以用任意精度的算术进行计算。这样,一些特殊的常数,比如e, pi, oo (无限), 可以被作为符号处理并且可以以任意精度来评估:" 118 | ] 119 | }, 120 | { 121 | "cell_type": "code", 122 | "execution_count": 4, 123 | "metadata": { 124 | "collapsed": false 125 | }, 126 | "outputs": [ 127 | { 128 | "data": { 129 | "text/plain": [ 130 | "pi**2" 131 | ] 132 | }, 133 | "execution_count": 4, 134 | "metadata": {}, 135 | "output_type": "execute_result" 136 | } 137 | ], 138 | "source": [ 139 | "pi**2" 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "execution_count": 5, 145 | "metadata": { 146 | "collapsed": false 147 | }, 148 | "outputs": [ 149 | { 150 | "data": { 151 | "text/plain": [ 152 | "3.14159265358979" 153 | ] 154 | }, 155 | "execution_count": 5, 156 | "metadata": {}, 157 | "output_type": "execute_result" 158 | } 159 | ], 160 | "source": [ 161 | "pi.evalf()" 162 | ] 163 | }, 164 | { 165 | "cell_type": "code", 166 | "execution_count": 6, 167 | "metadata": { 168 | "collapsed": false 169 | }, 170 | "outputs": [ 171 | { 172 | "data": { 173 | "text/plain": [ 174 | "5.85987448204884" 175 | ] 176 | }, 177 | "execution_count": 6, 178 | "metadata": {}, 179 | "output_type": "execute_result" 180 | } 181 | ], 182 | "source": [ 183 | "(pi + exp(1)).evalf()" 184 | ] 185 | }, 186 | { 187 | "cell_type": "markdown", 188 | "metadata": {}, 189 | "source": [ 190 | "如你所见,将表达式评估为浮点数。\n", 191 | "\n", 192 | "也有一个类代表数学的无限, 称为 oo:" 193 | ] 194 | }, 195 | { 196 | "cell_type": "code", 197 | "execution_count": 7, 198 | "metadata": { 199 | "collapsed": false 200 | }, 201 | "outputs": [ 202 | { 203 | "data": { 204 | "text/plain": [ 205 | "True" 206 | ] 207 | }, 208 | "execution_count": 7, 209 | "metadata": {}, 210 | "output_type": "execute_result" 211 | } 212 | ], 213 | "source": [ 214 | "oo > 99999" 215 | ] 216 | }, 217 | { 218 | "cell_type": "code", 219 | "execution_count": 8, 220 | "metadata": { 221 | "collapsed": false 222 | }, 223 | "outputs": [ 224 | { 225 | "data": { 226 | "text/plain": [ 227 | "oo" 228 | ] 229 | }, 230 | "execution_count": 8, 231 | "metadata": {}, 232 | "output_type": "execute_result" 233 | } 234 | ], 235 | "source": [ 236 | "oo + 1" 237 | ] 238 | }, 239 | { 240 | "cell_type": "markdown", 241 | "metadata": {}, 242 | "source": [ 243 | "### 3.2.1.2 练习\n", 244 | "\n", 245 | "- 计算 $\\sqrt{2}$ 小数点后一百位。\n", 246 | "- 用有理数算术计算1/2 + 1/3 in rational arithmetic.\n", 247 | "\n", 248 | "### 3.2.1.3 符号\n", 249 | "\n", 250 | "与其他计算机代数系统不同,在SymPy你需要显性声明符号变量:" 251 | ] 252 | }, 253 | { 254 | "cell_type": "code", 255 | "execution_count": 4, 256 | "metadata": { 257 | "collapsed": true 258 | }, 259 | "outputs": [], 260 | "source": [ 261 | "from sympy import *\n", 262 | "x = Symbol('x')\n", 263 | "y = Symbol('y')" 264 | ] 265 | }, 266 | { 267 | "cell_type": "markdown", 268 | "metadata": {}, 269 | "source": [ 270 | "然后你可以计算他们:" 271 | ] 272 | }, 273 | { 274 | "cell_type": "code", 275 | "execution_count": 10, 276 | "metadata": { 277 | "collapsed": false 278 | }, 279 | "outputs": [ 280 | { 281 | "data": { 282 | "text/plain": [ 283 | "2*x" 284 | ] 285 | }, 286 | "execution_count": 10, 287 | "metadata": {}, 288 | "output_type": "execute_result" 289 | } 290 | ], 291 | "source": [ 292 | "x + y + x - y" 293 | ] 294 | }, 295 | { 296 | "cell_type": "code", 297 | "execution_count": 11, 298 | "metadata": { 299 | "collapsed": false 300 | }, 301 | "outputs": [ 302 | { 303 | "data": { 304 | "text/plain": [ 305 | "(x + y)**2" 306 | ] 307 | }, 308 | "execution_count": 11, 309 | "metadata": {}, 310 | "output_type": "execute_result" 311 | } 312 | ], 313 | "source": [ 314 | "(x + y)**2" 315 | ] 316 | }, 317 | { 318 | "cell_type": "markdown", 319 | "metadata": {}, 320 | "source": [ 321 | "符号可以使用一些Python操作符操作: +, -, \\*, \\*\\* (算术), &, |, ~ , >>, << (布尔逻辑)." 322 | ] 323 | }, 324 | { 325 | "cell_type": "markdown", 326 | "metadata": {}, 327 | "source": [ 328 | "---\n", 329 | "\n", 330 | "**打印**\n", 331 | "这里我们使用下列设置打印\n", 332 | "\n", 333 | "---" 334 | ] 335 | }, 336 | { 337 | "cell_type": "code", 338 | "execution_count": null, 339 | "metadata": { 340 | "collapsed": true 341 | }, 342 | "outputs": [], 343 | "source": [ 344 | "sympy.init_printing(use_unicode=False, wrap_line=True)" 345 | ] 346 | }, 347 | { 348 | "cell_type": "markdown", 349 | "metadata": {}, 350 | "source": [ 351 | "## 3.2.2 代数运算\n", 352 | "\n", 353 | "SymPy可以进行强大的代数运算。我们将看一下最常使用的:展开和化简。\n", 354 | "\n", 355 | "### 3.2.2.1 展开\n", 356 | "\n", 357 | "使用这个模块展开代数表达式。它将试着密集的乘方和相乘:" 358 | ] 359 | }, 360 | { 361 | "cell_type": "code", 362 | "execution_count": 13, 363 | "metadata": { 364 | "collapsed": false 365 | }, 366 | "outputs": [ 367 | { 368 | "data": { 369 | "text/plain": [ 370 | "x**3 + 3*x**2*y + 3*x*y**2 + y**3" 371 | ] 372 | }, 373 | "execution_count": 13, 374 | "metadata": {}, 375 | "output_type": "execute_result" 376 | } 377 | ], 378 | "source": [ 379 | "expand((x + y)**3)" 380 | ] 381 | }, 382 | { 383 | "cell_type": "code", 384 | "execution_count": 14, 385 | "metadata": { 386 | "collapsed": false 387 | }, 388 | "outputs": [ 389 | { 390 | "data": { 391 | "text/plain": [ 392 | "x**3 + 3*x**2*y + 3*x*y**2 + y**3" 393 | ] 394 | }, 395 | "execution_count": 14, 396 | "metadata": {}, 397 | "output_type": "execute_result" 398 | } 399 | ], 400 | "source": [ 401 | "3*x*y**2 + 3*y*x**2 + x**3 + y**3" 402 | ] 403 | }, 404 | { 405 | "cell_type": "markdown", 406 | "metadata": {}, 407 | "source": [ 408 | "可以通过关键词的形式使用更多的选项:" 409 | ] 410 | }, 411 | { 412 | "cell_type": "code", 413 | "execution_count": 15, 414 | "metadata": { 415 | "collapsed": false 416 | }, 417 | "outputs": [ 418 | { 419 | "data": { 420 | "text/plain": [ 421 | "re(x) + re(y) + I*im(x) + I*im(y)" 422 | ] 423 | }, 424 | "execution_count": 15, 425 | "metadata": {}, 426 | "output_type": "execute_result" 427 | } 428 | ], 429 | "source": [ 430 | "expand(x + y, complex=True)" 431 | ] 432 | }, 433 | { 434 | "cell_type": "code", 435 | "execution_count": 16, 436 | "metadata": { 437 | "collapsed": false 438 | }, 439 | "outputs": [ 440 | { 441 | "data": { 442 | "text/plain": [ 443 | "re(x) + re(y) + I*im(x) + I*im(y)" 444 | ] 445 | }, 446 | "execution_count": 16, 447 | "metadata": {}, 448 | "output_type": "execute_result" 449 | } 450 | ], 451 | "source": [ 452 | "I*im(x) + I*im(y) + re(x) + re(y)" 453 | ] 454 | }, 455 | { 456 | "cell_type": "code", 457 | "execution_count": 17, 458 | "metadata": { 459 | "collapsed": false 460 | }, 461 | "outputs": [ 462 | { 463 | "data": { 464 | "text/plain": [ 465 | "-sin(x)*sin(y) + cos(x)*cos(y)" 466 | ] 467 | }, 468 | "execution_count": 17, 469 | "metadata": {}, 470 | "output_type": "execute_result" 471 | } 472 | ], 473 | "source": [ 474 | "expand(cos(x + y), trig=True)" 475 | ] 476 | }, 477 | { 478 | "cell_type": "code", 479 | "execution_count": 18, 480 | "metadata": { 481 | "collapsed": false 482 | }, 483 | "outputs": [ 484 | { 485 | "data": { 486 | "text/plain": [ 487 | "-sin(x)*sin(y) + cos(x)*cos(y)" 488 | ] 489 | }, 490 | "execution_count": 18, 491 | "metadata": {}, 492 | "output_type": "execute_result" 493 | } 494 | ], 495 | "source": [ 496 | "cos(x)*cos(y) - sin(x)*sin(y)" 497 | ] 498 | }, 499 | { 500 | "cell_type": "markdown", 501 | "metadata": {}, 502 | "source": [ 503 | "## 3.2.2.2 化简\n", 504 | "\n", 505 | "如果可以将表达式转化为更简单的形式,可以使用化简:" 506 | ] 507 | }, 508 | { 509 | "cell_type": "code", 510 | "execution_count": 19, 511 | "metadata": { 512 | "collapsed": false 513 | }, 514 | "outputs": [ 515 | { 516 | "data": { 517 | "text/plain": [ 518 | "y + 1" 519 | ] 520 | }, 521 | "execution_count": 19, 522 | "metadata": {}, 523 | "output_type": "execute_result" 524 | } 525 | ], 526 | "source": [ 527 | "simplify((x + x*y) / x)" 528 | ] 529 | }, 530 | { 531 | "cell_type": "markdown", 532 | "metadata": { 533 | "collapsed": true 534 | }, 535 | "source": [ 536 | "化简是一个模糊的术语,更准确的词应该是:powsimp (指数化简)、 trigsimp (三角表达式)、logcombine、radsimp一起。\n", 537 | "\n", 538 | "---\n", 539 | "\n", 540 | "**练习**\n", 541 | "- 计算$(x+y)^6$的展开。\n", 542 | "- 化简三角表达式$ \\sin(x) / \\cos(x)$\n", 543 | "\n", 544 | "---\n", 545 | "\n", 546 | "## 3.2.3 微积分\n", 547 | "\n", 548 | "### 3.2.3.1 极限\n", 549 | "\n", 550 | "在SymPy中使用极限很简单,允许语法limit(function, variable, point), 因此要计算f(x)类似$x \\rightarrow 0$, 你应该使用limit(f, x, 0):" 551 | ] 552 | }, 553 | { 554 | "cell_type": "code", 555 | "execution_count": 5, 556 | "metadata": { 557 | "collapsed": false 558 | }, 559 | "outputs": [ 560 | { 561 | "data": { 562 | "text/plain": [ 563 | "1" 564 | ] 565 | }, 566 | "execution_count": 5, 567 | "metadata": {}, 568 | "output_type": "execute_result" 569 | } 570 | ], 571 | "source": [ 572 | "limit(sin(x)/x, x, 0)" 573 | ] 574 | }, 575 | { 576 | "cell_type": "markdown", 577 | "metadata": {}, 578 | "source": [ 579 | "你也可以计算一下在无限时候的极限:" 580 | ] 581 | }, 582 | { 583 | "cell_type": "code", 584 | "execution_count": 6, 585 | "metadata": { 586 | "collapsed": false 587 | }, 588 | "outputs": [ 589 | { 590 | "data": { 591 | "text/plain": [ 592 | "oo" 593 | ] 594 | }, 595 | "execution_count": 6, 596 | "metadata": {}, 597 | "output_type": "execute_result" 598 | } 599 | ], 600 | "source": [ 601 | "limit(x, x, oo)" 602 | ] 603 | }, 604 | { 605 | "cell_type": "code", 606 | "execution_count": 7, 607 | "metadata": { 608 | "collapsed": false 609 | }, 610 | "outputs": [ 611 | { 612 | "data": { 613 | "text/plain": [ 614 | "0" 615 | ] 616 | }, 617 | "execution_count": 7, 618 | "metadata": {}, 619 | "output_type": "execute_result" 620 | } 621 | ], 622 | "source": [ 623 | "limit(1/x, x, oo)" 624 | ] 625 | }, 626 | { 627 | "cell_type": "code", 628 | "execution_count": 8, 629 | "metadata": { 630 | "collapsed": false 631 | }, 632 | "outputs": [ 633 | { 634 | "data": { 635 | "text/plain": [ 636 | "1" 637 | ] 638 | }, 639 | "execution_count": 8, 640 | "metadata": {}, 641 | "output_type": "execute_result" 642 | } 643 | ], 644 | "source": [ 645 | "limit(x**x, x, 0)" 646 | ] 647 | }, 648 | { 649 | "cell_type": "markdown", 650 | "metadata": {}, 651 | "source": [ 652 | "### 3.2.3.2 微分法\n", 653 | "\n", 654 | "你可以使用`diff(func, var)`微分任何SymPy表达式。例如:" 655 | ] 656 | }, 657 | { 658 | "cell_type": "code", 659 | "execution_count": 9, 660 | "metadata": { 661 | "collapsed": false 662 | }, 663 | "outputs": [ 664 | { 665 | "data": { 666 | "text/plain": [ 667 | "cos(x)" 668 | ] 669 | }, 670 | "execution_count": 9, 671 | "metadata": {}, 672 | "output_type": "execute_result" 673 | } 674 | ], 675 | "source": [ 676 | "diff(sin(x), x)" 677 | ] 678 | }, 679 | { 680 | "cell_type": "code", 681 | "execution_count": 10, 682 | "metadata": { 683 | "collapsed": false 684 | }, 685 | "outputs": [ 686 | { 687 | "data": { 688 | "text/plain": [ 689 | "2*cos(2*x)" 690 | ] 691 | }, 692 | "execution_count": 10, 693 | "metadata": {}, 694 | "output_type": "execute_result" 695 | } 696 | ], 697 | "source": [ 698 | "diff(sin(2*x), x)" 699 | ] 700 | }, 701 | { 702 | "cell_type": "code", 703 | "execution_count": 11, 704 | "metadata": { 705 | "collapsed": false 706 | }, 707 | "outputs": [ 708 | { 709 | "data": { 710 | "text/plain": [ 711 | "tan(x)**2 + 1" 712 | ] 713 | }, 714 | "execution_count": 11, 715 | "metadata": {}, 716 | "output_type": "execute_result" 717 | } 718 | ], 719 | "source": [ 720 | "diff(tan(x), x)" 721 | ] 722 | }, 723 | { 724 | "cell_type": "markdown", 725 | "metadata": {}, 726 | "source": [ 727 | "你可以用下列方法检查是否正确:" 728 | ] 729 | }, 730 | { 731 | "cell_type": "code", 732 | "execution_count": 12, 733 | "metadata": { 734 | "collapsed": false 735 | }, 736 | "outputs": [ 737 | { 738 | "data": { 739 | "text/plain": [ 740 | "tan(x)**2 + 1" 741 | ] 742 | }, 743 | "execution_count": 12, 744 | "metadata": {}, 745 | "output_type": "execute_result" 746 | } 747 | ], 748 | "source": [ 749 | "limit((tan(x+y) - tan(x))/y, y, 0)" 750 | ] 751 | }, 752 | { 753 | "cell_type": "markdown", 754 | "metadata": {}, 755 | "source": [ 756 | "可以用`diff(func, var, n)`方法来计算更高的导数:" 757 | ] 758 | }, 759 | { 760 | "cell_type": "code", 761 | "execution_count": 13, 762 | "metadata": { 763 | "collapsed": false 764 | }, 765 | "outputs": [ 766 | { 767 | "data": { 768 | "text/plain": [ 769 | "2*cos(2*x)" 770 | ] 771 | }, 772 | "execution_count": 13, 773 | "metadata": {}, 774 | "output_type": "execute_result" 775 | } 776 | ], 777 | "source": [ 778 | "diff(sin(2*x), x, 1)" 779 | ] 780 | }, 781 | { 782 | "cell_type": "code", 783 | "execution_count": 14, 784 | "metadata": { 785 | "collapsed": false 786 | }, 787 | "outputs": [ 788 | { 789 | "data": { 790 | "text/plain": [ 791 | "-4*sin(2*x)" 792 | ] 793 | }, 794 | "execution_count": 14, 795 | "metadata": {}, 796 | "output_type": "execute_result" 797 | } 798 | ], 799 | "source": [ 800 | "diff(sin(2*x), x, 2)" 801 | ] 802 | }, 803 | { 804 | "cell_type": "code", 805 | "execution_count": 15, 806 | "metadata": { 807 | "collapsed": false 808 | }, 809 | "outputs": [ 810 | { 811 | "data": { 812 | "text/plain": [ 813 | "-8*cos(2*x)" 814 | ] 815 | }, 816 | "execution_count": 15, 817 | "metadata": {}, 818 | "output_type": "execute_result" 819 | } 820 | ], 821 | "source": [ 822 | "diff(sin(2*x), x, 3)" 823 | ] 824 | }, 825 | { 826 | "cell_type": "markdown", 827 | "metadata": {}, 828 | "source": [ 829 | "### 3.2.3.3 序列展开\n", 830 | "\n", 831 | "SymPy也知道如何计算一个表达式在一个点的Taylor序列。使用`series(expr, var)`:" 832 | ] 833 | }, 834 | { 835 | "cell_type": "code", 836 | "execution_count": 16, 837 | "metadata": { 838 | "collapsed": false 839 | }, 840 | "outputs": [ 841 | { 842 | "data": { 843 | "text/plain": [ 844 | "1 - x**2/2 + x**4/24 + O(x**6)" 845 | ] 846 | }, 847 | "execution_count": 16, 848 | "metadata": {}, 849 | "output_type": "execute_result" 850 | } 851 | ], 852 | "source": [ 853 | "series(cos(x), x)" 854 | ] 855 | }, 856 | { 857 | "cell_type": "code", 858 | "execution_count": 17, 859 | "metadata": { 860 | "collapsed": false 861 | }, 862 | "outputs": [ 863 | { 864 | "data": { 865 | "text/plain": [ 866 | "1 + x**2/2 + 5*x**4/24 + O(x**6)" 867 | ] 868 | }, 869 | "execution_count": 17, 870 | "metadata": {}, 871 | "output_type": "execute_result" 872 | } 873 | ], 874 | "source": [ 875 | "series(1/cos(x), x)" 876 | ] 877 | }, 878 | { 879 | "cell_type": "markdown", 880 | "metadata": {}, 881 | "source": [ 882 | "---\n", 883 | "**练习**\n", 884 | "\n", 885 | "计算$\\lim_{x\\rightarrow 0} \\sin(x)/x$\n", 886 | "\n", 887 | "计算`log(x)`对于x的导数。\n", 888 | "\n", 889 | "---\n", 890 | "\n", 891 | "### 3.2.3.4 积分法\n", 892 | "\n", 893 | "SymPy支持超验基础和特殊函数的无限和有限积分,通过`integrate()` 功能, 使用了强大的扩展的Risch-Norman算法和启发式和模式匹配。你可以积分基本函数:" 894 | ] 895 | }, 896 | { 897 | "cell_type": "code", 898 | "execution_count": 18, 899 | "metadata": { 900 | "collapsed": false 901 | }, 902 | "outputs": [ 903 | { 904 | "data": { 905 | "text/plain": [ 906 | "x**6" 907 | ] 908 | }, 909 | "execution_count": 18, 910 | "metadata": {}, 911 | "output_type": "execute_result" 912 | } 913 | ], 914 | "source": [ 915 | "integrate(6*x**5, x)" 916 | ] 917 | }, 918 | { 919 | "cell_type": "code", 920 | "execution_count": 19, 921 | "metadata": { 922 | "collapsed": false 923 | }, 924 | "outputs": [ 925 | { 926 | "data": { 927 | "text/plain": [ 928 | "-cos(x)" 929 | ] 930 | }, 931 | "execution_count": 19, 932 | "metadata": {}, 933 | "output_type": "execute_result" 934 | } 935 | ], 936 | "source": [ 937 | "integrate(sin(x), x)" 938 | ] 939 | }, 940 | { 941 | "cell_type": "code", 942 | "execution_count": 20, 943 | "metadata": { 944 | "collapsed": false 945 | }, 946 | "outputs": [ 947 | { 948 | "data": { 949 | "text/plain": [ 950 | "x*log(x) - x" 951 | ] 952 | }, 953 | "execution_count": 20, 954 | "metadata": {}, 955 | "output_type": "execute_result" 956 | } 957 | ], 958 | "source": [ 959 | "integrate(log(x), x)" 960 | ] 961 | }, 962 | { 963 | "cell_type": "code", 964 | "execution_count": 21, 965 | "metadata": { 966 | "collapsed": false 967 | }, 968 | "outputs": [ 969 | { 970 | "data": { 971 | "text/plain": [ 972 | "x**2 + cosh(x)" 973 | ] 974 | }, 975 | "execution_count": 21, 976 | "metadata": {}, 977 | "output_type": "execute_result" 978 | } 979 | ], 980 | "source": [ 981 | "integrate(2*x + sinh(x), x)" 982 | ] 983 | }, 984 | { 985 | "cell_type": "markdown", 986 | "metadata": {}, 987 | "source": [ 988 | "也可以很简单的处理特殊函数:" 989 | ] 990 | }, 991 | { 992 | "cell_type": "code", 993 | "execution_count": 22, 994 | "metadata": { 995 | "collapsed": false 996 | }, 997 | "outputs": [ 998 | { 999 | "data": { 1000 | "text/plain": [ 1001 | "sqrt(pi)*erf(x)**2/4" 1002 | ] 1003 | }, 1004 | "execution_count": 22, 1005 | "metadata": {}, 1006 | "output_type": "execute_result" 1007 | } 1008 | ], 1009 | "source": [ 1010 | "integrate(exp(-x**2)*erf(x), x)" 1011 | ] 1012 | }, 1013 | { 1014 | "cell_type": "markdown", 1015 | "metadata": {}, 1016 | "source": [ 1017 | "也可以计算一下有限积分:" 1018 | ] 1019 | }, 1020 | { 1021 | "cell_type": "code", 1022 | "execution_count": 23, 1023 | "metadata": { 1024 | "collapsed": false 1025 | }, 1026 | "outputs": [ 1027 | { 1028 | "data": { 1029 | "text/plain": [ 1030 | "0" 1031 | ] 1032 | }, 1033 | "execution_count": 23, 1034 | "metadata": {}, 1035 | "output_type": "execute_result" 1036 | } 1037 | ], 1038 | "source": [ 1039 | "integrate(x**3, (x, -1, 1))" 1040 | ] 1041 | }, 1042 | { 1043 | "cell_type": "code", 1044 | "execution_count": 24, 1045 | "metadata": { 1046 | "collapsed": false 1047 | }, 1048 | "outputs": [ 1049 | { 1050 | "data": { 1051 | "text/plain": [ 1052 | "1" 1053 | ] 1054 | }, 1055 | "execution_count": 24, 1056 | "metadata": {}, 1057 | "output_type": "execute_result" 1058 | } 1059 | ], 1060 | "source": [ 1061 | "integrate(sin(x), (x, 0, pi/2))" 1062 | ] 1063 | }, 1064 | { 1065 | "cell_type": "code", 1066 | "execution_count": 25, 1067 | "metadata": { 1068 | "collapsed": false 1069 | }, 1070 | "outputs": [ 1071 | { 1072 | "data": { 1073 | "text/plain": [ 1074 | "2" 1075 | ] 1076 | }, 1077 | "execution_count": 25, 1078 | "metadata": {}, 1079 | "output_type": "execute_result" 1080 | } 1081 | ], 1082 | "source": [ 1083 | "integrate(cos(x), (x, -pi/2, pi/2))" 1084 | ] 1085 | }, 1086 | { 1087 | "cell_type": "markdown", 1088 | "metadata": {}, 1089 | "source": [ 1090 | "不标准积分也支持:" 1091 | ] 1092 | }, 1093 | { 1094 | "cell_type": "code", 1095 | "execution_count": 26, 1096 | "metadata": { 1097 | "collapsed": false 1098 | }, 1099 | "outputs": [ 1100 | { 1101 | "data": { 1102 | "text/plain": [ 1103 | "1" 1104 | ] 1105 | }, 1106 | "execution_count": 26, 1107 | "metadata": {}, 1108 | "output_type": "execute_result" 1109 | } 1110 | ], 1111 | "source": [ 1112 | "integrate(exp(-x), (x, 0, oo))" 1113 | ] 1114 | }, 1115 | { 1116 | "cell_type": "code", 1117 | "execution_count": 27, 1118 | "metadata": { 1119 | "collapsed": false 1120 | }, 1121 | "outputs": [ 1122 | { 1123 | "data": { 1124 | "text/plain": [ 1125 | "sqrt(pi)" 1126 | ] 1127 | }, 1128 | "execution_count": 27, 1129 | "metadata": {}, 1130 | "output_type": "execute_result" 1131 | } 1132 | ], 1133 | "source": [ 1134 | "integrate(exp(-x**2), (x, -oo, oo))" 1135 | ] 1136 | }, 1137 | { 1138 | "cell_type": "markdown", 1139 | "metadata": {}, 1140 | "source": [ 1141 | "#### 3.2.3.5 练习\n", 1142 | "\n", 1143 | "### 3.2.4 方程求解\n", 1144 | "\n", 1145 | "SymPy可以求解线性代数方程,一个或多个变量:" 1146 | ] 1147 | }, 1148 | { 1149 | "cell_type": "code", 1150 | "execution_count": 28, 1151 | "metadata": { 1152 | "collapsed": false 1153 | }, 1154 | "outputs": [ 1155 | { 1156 | "data": { 1157 | "text/plain": [ 1158 | "[-1, 1, -I, I]" 1159 | ] 1160 | }, 1161 | "execution_count": 28, 1162 | "metadata": {}, 1163 | "output_type": "execute_result" 1164 | } 1165 | ], 1166 | "source": [ 1167 | "solve(x**4 - 1, x)" 1168 | ] 1169 | }, 1170 | { 1171 | "cell_type": "markdown", 1172 | "metadata": {}, 1173 | "source": [ 1174 | "如你所见,第一个参数是假设等于0的表达式。它可以解一个很大的多项式方程,也可以有能力求解多个方程,可以将各自的多个变量作为元组以第二个参数给出:" 1175 | ] 1176 | }, 1177 | { 1178 | "cell_type": "code", 1179 | "execution_count": 29, 1180 | "metadata": { 1181 | "collapsed": false 1182 | }, 1183 | "outputs": [ 1184 | { 1185 | "data": { 1186 | "text/plain": [ 1187 | "{x: -3, y: 1}" 1188 | ] 1189 | }, 1190 | "execution_count": 29, 1191 | "metadata": {}, 1192 | "output_type": "execute_result" 1193 | } 1194 | ], 1195 | "source": [ 1196 | "solve([x + 5*y - 2, -3*x + 6*y - 15], [x, y])" 1197 | ] 1198 | }, 1199 | { 1200 | "cell_type": "markdown", 1201 | "metadata": {}, 1202 | "source": [ 1203 | "也直接求解超越方程(有限的):" 1204 | ] 1205 | }, 1206 | { 1207 | "cell_type": "code", 1208 | "execution_count": 30, 1209 | "metadata": { 1210 | "collapsed": false 1211 | }, 1212 | "outputs": [ 1213 | { 1214 | "data": { 1215 | "text/plain": [ 1216 | "[I*pi]" 1217 | ] 1218 | }, 1219 | "execution_count": 30, 1220 | "metadata": {}, 1221 | "output_type": "execute_result" 1222 | } 1223 | ], 1224 | "source": [ 1225 | "solve(exp(x) + 1, x)" 1226 | ] 1227 | }, 1228 | { 1229 | "cell_type": "markdown", 1230 | "metadata": {}, 1231 | "source": [ 1232 | "多项式方程的另一个应用是`factor`。`factor`将多项式因式分解为可化简的项,并且可以计算不同域的因式:" 1233 | ] 1234 | }, 1235 | { 1236 | "cell_type": "code", 1237 | "execution_count": 31, 1238 | "metadata": { 1239 | "collapsed": false 1240 | }, 1241 | "outputs": [ 1242 | { 1243 | "data": { 1244 | "text/plain": [ 1245 | "(x**2 - x - 1)*(x**2 + x - 1)" 1246 | ] 1247 | }, 1248 | "execution_count": 31, 1249 | "metadata": {}, 1250 | "output_type": "execute_result" 1251 | } 1252 | ], 1253 | "source": [ 1254 | "f = x**4 - 3*x**2 + 1\n", 1255 | "factor(f)" 1256 | ] 1257 | }, 1258 | { 1259 | "cell_type": "code", 1260 | "execution_count": 32, 1261 | "metadata": { 1262 | "collapsed": false 1263 | }, 1264 | "outputs": [ 1265 | { 1266 | "data": { 1267 | "text/plain": [ 1268 | "(x - 2)**2*(x + 2)**2" 1269 | ] 1270 | }, 1271 | "execution_count": 32, 1272 | "metadata": {}, 1273 | "output_type": "execute_result" 1274 | } 1275 | ], 1276 | "source": [ 1277 | "factor(f, modulus=5)" 1278 | ] 1279 | }, 1280 | { 1281 | "cell_type": "markdown", 1282 | "metadata": {}, 1283 | "source": [ 1284 | "SymPy也可以解布尔方程,即,判断一个布尔表达式是否满足。对于这个情况,我们可以使用`satisfiable`函数:" 1285 | ] 1286 | }, 1287 | { 1288 | "cell_type": "code", 1289 | "execution_count": 33, 1290 | "metadata": { 1291 | "collapsed": false 1292 | }, 1293 | "outputs": [ 1294 | { 1295 | "data": { 1296 | "text/plain": [ 1297 | "{x: True, y: True}" 1298 | ] 1299 | }, 1300 | "execution_count": 33, 1301 | "metadata": {}, 1302 | "output_type": "execute_result" 1303 | } 1304 | ], 1305 | "source": [ 1306 | "satisfiable(x & y)" 1307 | ] 1308 | }, 1309 | { 1310 | "cell_type": "markdown", 1311 | "metadata": {}, 1312 | "source": [ 1313 | "这告诉我们`(x & y)`是真,当x和y都是True的时候。如果一个表达式不是True,即它的任何参数值都无法使表达式为真,那么它将返回False:" 1314 | ] 1315 | }, 1316 | { 1317 | "cell_type": "code", 1318 | "execution_count": 34, 1319 | "metadata": { 1320 | "collapsed": false 1321 | }, 1322 | "outputs": [ 1323 | { 1324 | "data": { 1325 | "text/plain": [ 1326 | "False" 1327 | ] 1328 | }, 1329 | "execution_count": 34, 1330 | "metadata": {}, 1331 | "output_type": "execute_result" 1332 | } 1333 | ], 1334 | "source": [ 1335 | "satisfiable(x & ~x)" 1336 | ] 1337 | }, 1338 | { 1339 | "cell_type": "markdown", 1340 | "metadata": {}, 1341 | "source": [ 1342 | "### 3.2.4.1 练习\n", 1343 | "\n", 1344 | "- 求解系统方程$x + y = 2$, $2\\cdot x + y = 0$\n", 1345 | "- 是否存在布尔值,使$(~x | y) & (~y | x)$为真?\n", 1346 | "\n", 1347 | "### 3.2.5 线性代数\n", 1348 | "\n", 1349 | "#### 3.2.5.1 矩阵\n", 1350 | "\n", 1351 | "矩阵通过Matrix类的一个实例来创建:" 1352 | ] 1353 | }, 1354 | { 1355 | "cell_type": "code", 1356 | "execution_count": 35, 1357 | "metadata": { 1358 | "collapsed": false 1359 | }, 1360 | "outputs": [ 1361 | { 1362 | "data": { 1363 | "text/plain": [ 1364 | "Matrix([\n", 1365 | "[1, 0],\n", 1366 | "[0, 1]])" 1367 | ] 1368 | }, 1369 | "execution_count": 35, 1370 | "metadata": {}, 1371 | "output_type": "execute_result" 1372 | } 1373 | ], 1374 | "source": [ 1375 | "from sympy import Matrix\n", 1376 | "Matrix([[1,0], [0,1]])" 1377 | ] 1378 | }, 1379 | { 1380 | "cell_type": "markdown", 1381 | "metadata": {}, 1382 | "source": [ 1383 | "与NumPy数组不同,你也可以在里面放入符号:" 1384 | ] 1385 | }, 1386 | { 1387 | "cell_type": "code", 1388 | "execution_count": 36, 1389 | "metadata": { 1390 | "collapsed": false 1391 | }, 1392 | "outputs": [ 1393 | { 1394 | "data": { 1395 | "text/plain": [ 1396 | "Matrix([\n", 1397 | "[1, x],\n", 1398 | "[y, 1]])" 1399 | ] 1400 | }, 1401 | "execution_count": 36, 1402 | "metadata": {}, 1403 | "output_type": "execute_result" 1404 | } 1405 | ], 1406 | "source": [ 1407 | "x = Symbol('x')\n", 1408 | "y = Symbol('y')\n", 1409 | "A = Matrix([[1,x], [y,1]])\n", 1410 | "A" 1411 | ] 1412 | }, 1413 | { 1414 | "cell_type": "code", 1415 | "execution_count": 37, 1416 | "metadata": { 1417 | "collapsed": false 1418 | }, 1419 | "outputs": [ 1420 | { 1421 | "data": { 1422 | "text/plain": [ 1423 | "Matrix([\n", 1424 | "[x*y + 1, 2*x],\n", 1425 | "[ 2*y, x*y + 1]])" 1426 | ] 1427 | }, 1428 | "execution_count": 37, 1429 | "metadata": {}, 1430 | "output_type": "execute_result" 1431 | } 1432 | ], 1433 | "source": [ 1434 | "A**2" 1435 | ] 1436 | }, 1437 | { 1438 | "cell_type": "markdown", 1439 | "metadata": {}, 1440 | "source": [ 1441 | "### 3.2.5.2 微分方程\n", 1442 | "\n", 1443 | "SymPy可以解 (一些) 常规微分。要求解一个微分方程,使用`dsolve`。首先,通过传递cls=Function来创建一个未定义的符号函数:" 1444 | ] 1445 | }, 1446 | { 1447 | "cell_type": "code", 1448 | "execution_count": 38, 1449 | "metadata": { 1450 | "collapsed": true 1451 | }, 1452 | "outputs": [], 1453 | "source": [ 1454 | "f, g = symbols('f g', cls=Function)" 1455 | ] 1456 | }, 1457 | { 1458 | "cell_type": "markdown", 1459 | "metadata": {}, 1460 | "source": [ 1461 | "f 和 g是未定义函数。我们可以调用f(x), 并且它可以代表未知的函数:" 1462 | ] 1463 | }, 1464 | { 1465 | "cell_type": "code", 1466 | "execution_count": 39, 1467 | "metadata": { 1468 | "collapsed": false 1469 | }, 1470 | "outputs": [ 1471 | { 1472 | "data": { 1473 | "text/plain": [ 1474 | "f(x)" 1475 | ] 1476 | }, 1477 | "execution_count": 39, 1478 | "metadata": {}, 1479 | "output_type": "execute_result" 1480 | } 1481 | ], 1482 | "source": [ 1483 | "f(x)" 1484 | ] 1485 | }, 1486 | { 1487 | "cell_type": "code", 1488 | "execution_count": 40, 1489 | "metadata": { 1490 | "collapsed": false 1491 | }, 1492 | "outputs": [ 1493 | { 1494 | "data": { 1495 | "text/plain": [ 1496 | "f(x) + Derivative(f(x), x, x)" 1497 | ] 1498 | }, 1499 | "execution_count": 40, 1500 | "metadata": {}, 1501 | "output_type": "execute_result" 1502 | } 1503 | ], 1504 | "source": [ 1505 | "f(x).diff(x, x) + f(x)" 1506 | ] 1507 | }, 1508 | { 1509 | "cell_type": "code", 1510 | "execution_count": 41, 1511 | "metadata": { 1512 | "collapsed": false 1513 | }, 1514 | "outputs": [ 1515 | { 1516 | "data": { 1517 | "text/plain": [ 1518 | "f(x) == C1*sin(x) + C2*cos(x)" 1519 | ] 1520 | }, 1521 | "execution_count": 41, 1522 | "metadata": {}, 1523 | "output_type": "execute_result" 1524 | } 1525 | ], 1526 | "source": [ 1527 | "dsolve(f(x).diff(x, x) + f(x), f(x))" 1528 | ] 1529 | }, 1530 | { 1531 | "cell_type": "markdown", 1532 | "metadata": {}, 1533 | "source": [ 1534 | "关键词参数可以向这个函数传递,以便帮助确认是否找到最适合的解决系统。例如,你知道它是独立的方程,你可以使用关键词hint=’separable’来强制`dsolve`来将它作为独立方程来求解:" 1535 | ] 1536 | }, 1537 | { 1538 | "cell_type": "code", 1539 | "execution_count": 42, 1540 | "metadata": { 1541 | "collapsed": false 1542 | }, 1543 | "outputs": [ 1544 | { 1545 | "data": { 1546 | "text/plain": [ 1547 | "[f(x) == -asin(sqrt(C1/cos(x)**2 + 1)) + pi,\n", 1548 | " f(x) == asin(sqrt(C1/cos(x)**2 + 1)) + pi,\n", 1549 | " f(x) == -asin(sqrt(C1/cos(x)**2 + 1)),\n", 1550 | " f(x) == asin(sqrt(C1/cos(x)**2 + 1))]" 1551 | ] 1552 | }, 1553 | "execution_count": 42, 1554 | "metadata": {}, 1555 | "output_type": "execute_result" 1556 | } 1557 | ], 1558 | "source": [ 1559 | "dsolve(sin(x)*cos(f(x)) + cos(x)*sin(f(x))*f(x).diff(x), f(x), hint='separable')" 1560 | ] 1561 | }, 1562 | { 1563 | "cell_type": "markdown", 1564 | "metadata": {}, 1565 | "source": [ 1566 | "---\n", 1567 | "**练习**\n", 1568 | "- 求解Bernoulli微分方程\n", 1569 | "\n", 1570 | " $x \\frac{d f(x)}{x} + f(x) - f(x)^2=0$\n", 1571 | "- 使用hint=’Bernoulli’求解相同的公式。可以观察到什么?\n", 1572 | "---" 1573 | ] 1574 | } 1575 | ], 1576 | "metadata": { 1577 | "kernelspec": { 1578 | "display_name": "Python 2", 1579 | "language": "python", 1580 | "name": "python2" 1581 | }, 1582 | "language_info": { 1583 | "codemirror_mode": { 1584 | "name": "ipython", 1585 | "version": 2 1586 | }, 1587 | "file_extension": ".py", 1588 | "mimetype": "text/x-python", 1589 | "name": "python", 1590 | "nbconvert_exporter": "python", 1591 | "pygments_lexer": "ipython2", 1592 | "version": "2.7.11" 1593 | } 1594 | }, 1595 | "nbformat": 4, 1596 | "nbformat_minor": 0 1597 | } 1598 | -------------------------------------------------------------------------------- /3.3. Scikit-image:图像处理.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": false 7 | }, 8 | "source": [ 9 | "> **作者**: Emmanuelle Gouillart\n", 10 | "\n", 11 | "[scikit-image](http://scikit-image.org/)是专注于图像处理的Python包,并且使用原生的Numpy数组作为图像对象。本章描述如何在不同图像处理任务上使用`scikit-image`,并且保留了其他科学Python模块比如Numpy和Scipy的链接。\n", 12 | "\n", 13 | "---\n", 14 | "**也可以看一下:**对于基本图像处理,比如图像剪切或者简单过滤,大量简单操作可以用Numpy和SciPy来实现。看一下[使用Numpy和Scipy图像操作和处理部分](http://www.scipy-lectures.org/advanced/image_processing/index.html#basic-image)。\n", 15 | "\n", 16 | "注意,在阅读本章之前你应该熟悉前面章节的内容,比如基础操作,比如面具和标签作为先决条件。\n", 17 | "\n", 18 | "---\n", 19 | "\n", 20 | "---\n", 21 | "**章节内容**\n", 22 | "- **介绍和观点**\n", 23 | " - `scikit-image` 和 `SciPy`生态系统\n", 24 | " - `scikit-image`能发现什么\n", 25 | "- **输入/输出, 数据类型和 颜色空间**\n", 26 | " - 数据类型\n", 27 | " - 颜色空间\n", 28 | "- **图像预处理/增强**\n", 29 | " - 本地过滤器\n", 30 | " - 非-本地过滤器\n", 31 | " - 数学形态学\n", 32 | "- **图像细分**\n", 33 | " - 二元细分: 前景 + 背景\n", 34 | " - 基于标记的方法\n", 35 | "- **测量区域的属性**\n", 36 | "- **数据可视化和交互**\n", 37 | "\n", 38 | "## 3.3.1 介绍和观点\n", 39 | "\n", 40 | "图像是NumPy的数组`np.ndarray`\n", 41 | "\n", 42 | "|图像:\t|np.ndarray|\n", 43 | "|--|--|\n", 44 | "|像素:|array values: a[2, 3]|\n", 45 | "|渠道:|array dimensions|\n", 46 | "|图像编码:|dtype (np.uint8, np.uint16, np.float)|\n", 47 | "|过滤器:|functions (numpy, skimage, scipy)|" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": 1, 53 | "metadata": { 54 | "collapsed": false 55 | }, 56 | "outputs": [ 57 | { 58 | "data": { 59 | "text/plain": [ 60 | "" 61 | ] 62 | }, 63 | "execution_count": 1, 64 | "metadata": {}, 65 | "output_type": "execute_result" 66 | }, 67 | { 68 | "data": { 69 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAPYAAAD7CAYAAABZjGkWAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAACTFJREFUeJzt3dHr3XUdx/Hnq02jJeilqINZKFhUOEKGEpHsYohpF4FJ\nEnjRVeYKErX/IVQIL9IliKUXM0RBEiLvAnE5NbcZKkpuMZQiQ6+2fHfxOxc/3PY739/vnO85O2+e\nDxB2zsbvvD/i08/Z9/s935OqQlIvn1v2AJLmz7ClhgxbasiwpYYMW2rIsKWGts/6A5J4vkxaoqrK\nZ5+bOexFWMS59uSMfzdz5zqGcx2z8a241JBhSw0ZttSQYUsNGbbUkGFLDU0NO8m+JG8meSvJvYsY\nStJsstG5vCTbgL8De4ETwMvA7VV1bN2fGf1kYJfzja5jONcx3NkuUJm2Y18HvF1V71XVKeAp4NYx\nhpM0P9PCvhx4f93j45PnJJ3HpoXtdeDSCpoW9glg57rHO1nbtSWdx6aFfQi4KsmuJBcCtwHPjj+W\npFls+Omuqjqd5C7gBWAbcGD9EXFJ56cNT3cN+gGe7hrMdQznOobbyukuSSvIsKWGDFtqyLClhgxb\nasiwpYYMW2poLrcfHvt8oOc0h3Mdw3VYx7nW4I4tNWTYUkOGLTVk2FJDhi01ZNhSQ4YtNWTYUkOG\nLTVk2FJDhi01ZNhSQ4YtNWTYUkOGLTVk2FJDhi01ZNhSQ4YtNWTYUkOGLTVk2FJDhi01ZNhSQ3P5\nwoCxb7zuzeOHcx3DdVnH2bhjSw0ZttSQYUsNGbbUkGFLDRm21JBhSw1NDTvJziQvJjmS5I0kdy9i\nMElbl2kn6ZNcClxaVa8muQj4K/C9qjo2+f3Rz/J3uZDAdQznOoarqjNeZOqOXVUnq+rVya8/Bo4B\nl81/PEnzsqm/YyfZBVwLvDTGMJLmY3DYk7fhB4H9k51b0nlqUNhJLgCeBp6oqmfGHUnSrIYcFQ9w\nADhaVQ+OP5KkWQ3ZsW8A7gC+k+Tw5J99I88laQZTT3dN/QGe7hrMdQznOobb0ukuSavHsKWGDFtq\nyLClhgxbasiwpYYMW2rIsKWG5vKFAWOf6PdiheFcx3Ad1nGuNbhjSw0ZttSQYUsNGbbUkGFLDRm2\n1JBhSw0ZttSQYUsNGbbUkGFLDRm21JBhSw0ZttSQYUsNGbbUkGFLDRm21JBhSw0ZttSQYUsNGbbU\nkGFLDRm21NBcvjBg7Buve/P44VzHcF3WcTbu2FJDhi01ZNhSQ4YtNWTYUkOGLTVk2FJDg8JOsi3J\n4STPjT2QpNkN3bH3A0eB8c/oS5rZ1LCTXAHcBDwKLOcyGkmbMmTHfgC4B/h05FkkzcmGYSe5Gfig\nqg7jbi2tjGk79vXALUneBZ4Ebkzy+PhjSZpFhn7CJcm3gV9U1Xc/8/zoB9S6fArHdQznOoarqjNe\nZLPnsT0qLq2AwTv2OX+AO/ZgrmM41zHcPHZsSSvAsKWGDFtqyLClhgxbasiwpYYMW2poLvcVH/t8\noOc0h3Mdw3VYx7nW4I4tNWTYUkOGLTVk2FJDhi01ZNhSQ4YtNWTYUkOGLTVk2FJDhi01ZNhSQ4Yt\nNWTYUkOGLTVk2FJDhi01ZNhSQ4YtNWTYUkOGLTVk2FJDhi01ZNhSQ3P5woCxb7zuzeOHcx3DdVnH\n2bhjSw0ZttSQYUsNGbbUkGFLDRm21JBhSw1NDTvJJUkOJjmW5GiSPYsYTNLWDblA5SHg+ar6fpLt\nwBdHnknSjLLR1TdJLgYOV9WXNvgzo1++0+UKIdcxnOsYrqrOeJFpb8WvBD5M8liSV5I8kmTHOONJ\nmpdpYW8HdgMPV9Vu4BPgvtGnkjSTaWEfB45X1cuTxwdZC13SeWzDsKvqJPB+kqsnT+0Fjow+laSZ\nbHjwDCDJN4BHgQuBd4A7q+qjdb/vwbOBXMdwrmO4sx08mxr2NIY9nOsYznUMt5Wj4pJWkGFLDRm2\n1JBhSw0ZttSQYUsNGbbUkGFLDc3lCwPGPtHvxQrDuY7hOqzjXGtwx5YaMmypIcOWGjJsqSHDlhoy\nbKkhw5YaMmypIcOWGjJsqSHDlhoybKkhw5YaMmypIcOWGjJsqSHDlhoybKkhw5YaMmypIcOWGjJs\nqSHDlhoybKmhuXxhwNg3Xvfm8cO5juG6rONs3LGlhgxbasiwpYYMW2rIsKWGDFtqyLClhqaGneT+\nJEeS/C3J75N8fhGDSdq6DcNOsgv4MbC7qr4GbAN+MP5YkmYx7cqz/wKngB1J/gfsAE6MPpWkmWy4\nY1fVv4FfAf8A/gn8p6r+tIjBJG3dtLfiXwZ+BuwCLgMuSvLDBcwlaQbTDp59E/hLVf2rqk4DfwCu\nH38sSbOYFvabwJ4kX8jax1T2AkfHH0vSLKb9Hfs14HHgEPD65OnfjD2UpNlk1s+kJhn9Q61dPjfr\nOoZzHcNV1Rkv4pVnUkOGLTVk2FJDhi01ZNhSQ4YtNWTYUkOGLTW0EheoSDq3s12gMnPYks4/vhWX\nGjJsqaGFhp1kX5I3k7yV5N5Fvva8JNmZ5MXJDR7fSHL3smfaqiTbkhxO8tyyZ9mqJJckOZjkWJKj\nSfYse6atmPdNQxcWdpJtwK+BfcBXgNuTXLOo15+jU8DPq+qrwB7gJyu6DoD9rH2+fpUPtDwEPF9V\n1wBfB44teZ5NG+OmoYvcsa8D3q6q96rqFPAUcOsCX38uqupkVb06+fXHrP2HdNlyp9q8JFcANwGP\nAsv5rtcZJbkY+FZV/Ragqk5X1UdLHmsr1t80dDtzuGnoIsO+HHh/3ePjk+dW1uT/tNcCLy13ki15\nALgH+HTZg8zgSuDDJI8leSXJI0l2LHuozRrjpqGLDHuV3+6dIclFwEFg/2TnXhlJbgY+qKrDrOhu\nPbEd2A08XFW7gU+A+5Y70uaNcdPQRYZ9Ati57vFO1nbtlZPkAuBp4ImqembZ82zB9cAtSd4FngRu\nTPL4kmfaiuPA8ap6efL4IGuhr5q53zR0kWEfAq5KsivJhcBtwLMLfP25mNzU8QBwtKoeXPY8W1FV\nv6yqnVV1JWsHaf5cVT9a9lybVVUngfeTXD15ai9wZIkjbdXcbxo67ZtA5qaqTie5C3iBtaN+B6pq\n5Y5gAjcAdwCvJzk8ee7+qvrjEmea1Sr/NemnwO8mm8U7wJ1LnmfTquq1yTumQ6wd83iFGW8a6iWl\nUkNeeSY1ZNhSQ4YtNWTYUkOGLTVk2FJDhi01ZNhSQ/8Hozm9KbkpidsAAAAASUVORK5CYII=\n", 70 | "text/plain": [ 71 | "" 72 | ] 73 | }, 74 | "metadata": {}, 75 | "output_type": "display_data" 76 | } 77 | ], 78 | "source": [ 79 | "%matplotlib inline\n", 80 | "import numpy as np\n", 81 | "check = np.zeros((9, 9))\n", 82 | "check[::2, 1::2] = 1\n", 83 | "check[1::2, ::2] = 1\n", 84 | "import matplotlib.pyplot as plt\n", 85 | "plt.imshow(check, cmap='gray', interpolation='nearest') " 86 | ] 87 | }, 88 | { 89 | "cell_type": "markdown", 90 | "metadata": {}, 91 | "source": [ 92 | "### 3.3.1.1 scikit-image 和 SciPy 生态系统\n", 93 | "\n", 94 | "最新版的`scikit-image`包含在大多数的科学Python发行版中,比如,Anaconda或Enthought Canopy。它也包含在 Ubuntu/Debian。" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": 3, 100 | "metadata": { 101 | "collapsed": false 102 | }, 103 | "outputs": [], 104 | "source": [ 105 | "import skimage\n", 106 | "from skimage import data # 大多数函数在子包中" 107 | ] 108 | }, 109 | { 110 | "cell_type": "markdown", 111 | "metadata": {}, 112 | "source": [ 113 | "大多数`scikit-image`函数用NumPy ndarrays作为参数" 114 | ] 115 | }, 116 | { 117 | "cell_type": "code", 118 | "execution_count": 6, 119 | "metadata": { 120 | "collapsed": false 121 | }, 122 | "outputs": [ 123 | { 124 | "data": { 125 | "text/plain": [ 126 | "dtype('uint8')" 127 | ] 128 | }, 129 | "execution_count": 6, 130 | "metadata": {}, 131 | "output_type": "execute_result" 132 | } 133 | ], 134 | "source": [ 135 | "camera = data.camera()\n", 136 | "camera.dtype" 137 | ] 138 | }, 139 | { 140 | "cell_type": "code", 141 | "execution_count": 7, 142 | "metadata": { 143 | "collapsed": false 144 | }, 145 | "outputs": [ 146 | { 147 | "data": { 148 | "text/plain": [ 149 | "(512, 512)" 150 | ] 151 | }, 152 | "execution_count": 7, 153 | "metadata": {}, 154 | "output_type": "execute_result" 155 | } 156 | ], 157 | "source": [ 158 | "camera.shape" 159 | ] 160 | }, 161 | { 162 | "cell_type": "code", 163 | "execution_count": 8, 164 | "metadata": { 165 | "collapsed": false 166 | }, 167 | "outputs": [ 168 | { 169 | "data": { 170 | "text/plain": [ 171 | "numpy.ndarray" 172 | ] 173 | }, 174 | "execution_count": 8, 175 | "metadata": {}, 176 | "output_type": "execute_result" 177 | } 178 | ], 179 | "source": [ 180 | "from skimage import restoration\n", 181 | "filtered_camera = restoration.denoise_bilateral(camera)\n", 182 | "type(filtered_camera) " 183 | ] 184 | }, 185 | { 186 | "cell_type": "markdown", 187 | "metadata": {}, 188 | "source": [ 189 | "其他Python包也可以用于图像处理,并且使用Numpy数组:\n", 190 | "- [scipy.ndimage](http://docs.scipy.org/doc/scipy/reference/ndimage.html#module-scipy.ndimage) : 对于 nd-arrays。基础过滤、数学形态学和区域属性\n", 191 | "- [Mahotas](http://luispedro.org/software/mahotas)\n", 192 | "同时,强大的图形处理库有Python封装:\n", 193 | "- [OpenCV](https://opencv-python-tutroals.readthedocs.org/en/latest/) (计算机视觉)\n", 194 | "- [ITK](http://www.itk.org/itkindex.html) (3D图像和注册)\n", 195 | "- 其他\n", 196 | "(但是,他们没有那么Pythonic也没有Numpy友好,在一定范围)。\n", 197 | "\n", 198 | "### 3.3.1.2 scikit-image能发现什么\n", 199 | "\n", 200 | "- 网站: http://scikit-image.org/\n", 201 | "- 例子库 (就像在 [matplotlib](http://matplotlib.org/gallery.html) 或 [scikit-learn](http://scikit-learn.org/)): http://scikit-image.org/docs/stable/auto_examples/ 不同类的函数,从基本的使用函数到高级最新算法。\n", 202 | "\n", 203 | "- 过滤器: 函数将图像转化为其他图像。\n", 204 | " - NumPy组件\n", 205 | " - 通用过滤器算法\n", 206 | "- 数据简化函数: 计算图像直方图、局部极值位置、角。\n", 207 | "- 其他动作: I/O, 可视化,等。\n", 208 | "\n", 209 | "## 3.3.2 输入/输出, 数据类型和颜色空间\n", 210 | "\n", 211 | "I/O: [skimage.io](http://scikit-image.org/docs/stable/api/skimage.io.html#module-skimage.io)" 212 | ] 213 | }, 214 | { 215 | "cell_type": "code", 216 | "execution_count": 4, 217 | "metadata": { 218 | "collapsed": true 219 | }, 220 | "outputs": [], 221 | "source": [ 222 | "from skimage import io" 223 | ] 224 | }, 225 | { 226 | "cell_type": "markdown", 227 | "metadata": {}, 228 | "source": [ 229 | "读取文件: [skimage.io.imread()](http://scikit-image.org/docs/stable/api/skimage.io.html#skimage.io.imread)" 230 | ] 231 | }, 232 | { 233 | "cell_type": "code", 234 | "execution_count": 7, 235 | "metadata": { 236 | "collapsed": false 237 | }, 238 | "outputs": [], 239 | "source": [ 240 | "import os\n", 241 | "filename = os.path.join(skimage.data_dir, 'camera.png')\n", 242 | "camera = io.imread(filename)" 243 | ] 244 | }, 245 | { 246 | "cell_type": "markdown", 247 | "metadata": {}, 248 | "source": [ 249 | "![](http://www.scipy-lectures.org/_images/plot_camera_1.png)\n", 250 | "\n", 251 | "支持所有被Python Imaging Library(或者`imread` `plugin`关键词提供的任何I/O插件)的数据格式。\n", 252 | "也支持URL图片路径:" 253 | ] 254 | }, 255 | { 256 | "cell_type": "code", 257 | "execution_count": 3, 258 | "metadata": { 259 | "collapsed": false 260 | }, 261 | "outputs": [], 262 | "source": [ 263 | "logo = io.imread('http://scikit-image.org/_static/img/logo.png')" 264 | ] 265 | }, 266 | { 267 | "cell_type": "markdown", 268 | "metadata": {}, 269 | "source": [ 270 | "存储文件:" 271 | ] 272 | }, 273 | { 274 | "cell_type": "code", 275 | "execution_count": 4, 276 | "metadata": { 277 | "collapsed": true 278 | }, 279 | "outputs": [], 280 | "source": [ 281 | "io.imsave('local_logo.png', logo)" 282 | ] 283 | }, 284 | { 285 | "cell_type": "markdown", 286 | "metadata": {}, 287 | "source": [ 288 | "(`imsave`也用外部插件比如PIL)\n", 289 | "\n", 290 | "### 3.3.2.1 数据类型\n", 291 | "\n", 292 | "![](http://www.scipy-lectures.org/_images/plot_camera_uint_1.png)\n", 293 | "\n", 294 | "图像ndarrays可以用整数(有符号或无符号)或浮点来代表。\n", 295 | "\n", 296 | "小心整数类型的溢出" 297 | ] 298 | }, 299 | { 300 | "cell_type": "code", 301 | "execution_count": 8, 302 | "metadata": { 303 | "collapsed": false 304 | }, 305 | "outputs": [ 306 | { 307 | "data": { 308 | "text/plain": [ 309 | "dtype('uint8')" 310 | ] 311 | }, 312 | "execution_count": 8, 313 | "metadata": {}, 314 | "output_type": "execute_result" 315 | } 316 | ], 317 | "source": [ 318 | "camera = data.camera()\n", 319 | "camera.dtype" 320 | ] 321 | }, 322 | { 323 | "cell_type": "code", 324 | "execution_count": 8, 325 | "metadata": { 326 | "collapsed": true 327 | }, 328 | "outputs": [], 329 | "source": [ 330 | "camera_multiply = 3 * camera" 331 | ] 332 | }, 333 | { 334 | "cell_type": "markdown", 335 | "metadata": {}, 336 | "source": [ 337 | "可用不同的整型大小: 8-, 16- 或 32-字节, 有符号或无符号。\n", 338 | "\n", 339 | "---\n", 340 | "一个重要的 (如果有疑问的话) `skimage` **惯例**: 图像浮点支持在[-1, 1] (与所以浮点图像相对)\n", 341 | "\n", 342 | "---" 343 | ] 344 | }, 345 | { 346 | "cell_type": "code", 347 | "execution_count": 9, 348 | "metadata": { 349 | "collapsed": false 350 | }, 351 | "outputs": [ 352 | { 353 | "data": { 354 | "text/plain": [ 355 | "(255, 1.0)" 356 | ] 357 | }, 358 | "execution_count": 9, 359 | "metadata": {}, 360 | "output_type": "execute_result" 361 | } 362 | ], 363 | "source": [ 364 | "from skimage import img_as_float\n", 365 | "camera_float = img_as_float(camera)\n", 366 | "camera.max(), camera_float.max()" 367 | ] 368 | }, 369 | { 370 | "cell_type": "markdown", 371 | "metadata": { 372 | "collapsed": true 373 | }, 374 | "source": [ 375 | "一些图像处理程序需要应用在浮点数组上,因此,输出的数组可能类型和数据范围都与输入数组不同" 376 | ] 377 | }, 378 | { 379 | "cell_type": "code", 380 | "execution_count": 9, 381 | "metadata": { 382 | "collapsed": false 383 | }, 384 | "outputs": [ 385 | { 386 | "data": { 387 | "text/plain": [ 388 | "0.5915023652179584" 389 | ] 390 | }, 391 | "execution_count": 9, 392 | "metadata": {}, 393 | "output_type": "execute_result" 394 | } 395 | ], 396 | "source": [ 397 | "try:\n", 398 | " from skimage import filters\n", 399 | "except ImportError:\n", 400 | " from skimage import filter as filters\n", 401 | "camera_sobel = filters.sobel(camera)\n", 402 | "camera_sobel.max() " 403 | ] 404 | }, 405 | { 406 | "cell_type": "markdown", 407 | "metadata": {}, 408 | "source": [ 409 | "---\n", 410 | "在上面的例子中,我们使用`scikit-image`的子模块`filters`,在0.11到0.10版本间,`filter`被重命名为`filters`,为了避免与Python内置的`filter`冲突。\n", 411 | "\n", 412 | "---\n", 413 | "\n", 414 | "在[skimage](http://scikit-image.org/docs/stable/api/skimage.html#module-skimage)提供了下列skimage实用的函数来转化dtype和data range: `util.img_as_float`、 `util.img_as_ubyte`等。\n", 415 | "\n", 416 | "看一下[用户手册](http://scikit-image.org/docs/stable/user_guide/data_types.html)来了解细节。\n", 417 | "\n", 418 | "### 3.3.2.2 颜色空间\n", 419 | "\n", 420 | "颜色图像是 (N, M, 3) 或 (N, M, 4) 形状 (当alpha渠道编码为透明度)\n" 421 | ] 422 | }, 423 | { 424 | "cell_type": "code", 425 | "execution_count": 6, 426 | "metadata": { 427 | "collapsed": false 428 | }, 429 | "outputs": [ 430 | { 431 | "data": { 432 | "text/plain": [ 433 | "(768, 1024, 3)" 434 | ] 435 | }, 436 | "execution_count": 6, 437 | "metadata": {}, 438 | "output_type": "execute_result" 439 | } 440 | ], 441 | "source": [ 442 | "import scipy\n", 443 | "face = scipy.misc.face()\n", 444 | "face.shape" 445 | ] 446 | }, 447 | { 448 | "cell_type": "markdown", 449 | "metadata": {}, 450 | "source": [ 451 | "[skimage.color](http://scikit-image.org/docs/stable/api/skimage.color.html#module-skimage.color)中包含转换不同颜色空间(RGB、HSV、LAB 等)的程序: `color.rgb2hsv`、color.lab2rgb等。检查一下文档字符串了解一下输入图像期望的dtype。\n", 452 | "\n", 453 | "---\n", 454 | "3D 图像\n", 455 | "`skimage`的大多数函数可以接受3D图像作为参数。看一些文档字符串确认一下函数是否可以被用于3D图像(例如MRI或CT图像)。\n", 456 | "---\n", 457 | "\n", 458 | "---\n", 459 | "练习\n", 460 | "\n", 461 | "在硬盘上打开一个颜色图像作为Numpy数组。\n", 462 | "\n", 463 | "找一个图像函数计算图像的直方图,并且打印每个颜色通道的直方图。\n", 464 | "\n", 465 | "将图像转换为灰度图,打印直方图。\n", 466 | "---\n", 467 | "\n", 468 | "## 3.3.3 图像预处理 / 增强\n", 469 | "\n", 470 | "目的: 降噪、特征 (边缘) 抽取 ...\n", 471 | "\n", 472 | "### 3.3.3.1 本地过滤器\n", 473 | "\n", 474 | "本地过滤器用一个函数替换像素临近像素的值。这个函数可以是线性或非线性的。\n", 475 | "\n", 476 | "临近: 方块 (选择大小)、磁盘、或更复杂的结构化元素。\n", 477 | "\n", 478 | "![](http://www.scipy-lectures.org/_images/kernels1.png)" 479 | ] 480 | }, 481 | { 482 | "cell_type": "code", 483 | "execution_count": null, 484 | "metadata": { 485 | "collapsed": true 486 | }, 487 | "outputs": [], 488 | "source": [] 489 | }, 490 | { 491 | "cell_type": "code", 492 | "execution_count": null, 493 | "metadata": { 494 | "collapsed": true 495 | }, 496 | "outputs": [], 497 | "source": [] 498 | }, 499 | { 500 | "cell_type": "code", 501 | "execution_count": null, 502 | "metadata": { 503 | "collapsed": true 504 | }, 505 | "outputs": [], 506 | "source": [] 507 | }, 508 | { 509 | "cell_type": "code", 510 | "execution_count": null, 511 | "metadata": { 512 | "collapsed": true 513 | }, 514 | "outputs": [], 515 | "source": [] 516 | }, 517 | { 518 | "cell_type": "code", 519 | "execution_count": null, 520 | "metadata": { 521 | "collapsed": true 522 | }, 523 | "outputs": [], 524 | "source": [] 525 | }, 526 | { 527 | "cell_type": "code", 528 | "execution_count": null, 529 | "metadata": { 530 | "collapsed": true 531 | }, 532 | "outputs": [], 533 | "source": [ 534 | "An important (if questionable) skimage convention: float images are supposed to lie in [-1, 1] (in order to have comparable contrast for all float images)" 535 | ] 536 | }, 537 | { 538 | "cell_type": "code", 539 | "execution_count": null, 540 | "metadata": { 541 | "collapsed": true 542 | }, 543 | "outputs": [], 544 | "source": [] 545 | }, 546 | { 547 | "cell_type": "code", 548 | "execution_count": null, 549 | "metadata": { 550 | "collapsed": true 551 | }, 552 | "outputs": [], 553 | "source": [] 554 | }, 555 | { 556 | "cell_type": "code", 557 | "execution_count": null, 558 | "metadata": { 559 | "collapsed": true 560 | }, 561 | "outputs": [], 562 | "source": [] 563 | }, 564 | { 565 | "cell_type": "code", 566 | "execution_count": null, 567 | "metadata": { 568 | "collapsed": true 569 | }, 570 | "outputs": [], 571 | "source": [] 572 | }, 573 | { 574 | "cell_type": "code", 575 | "execution_count": null, 576 | "metadata": { 577 | "collapsed": true 578 | }, 579 | "outputs": [], 580 | "source": [] 581 | }, 582 | { 583 | "cell_type": "code", 584 | "execution_count": null, 585 | "metadata": { 586 | "collapsed": true 587 | }, 588 | "outputs": [], 589 | "source": [] 590 | }, 591 | { 592 | "cell_type": "code", 593 | "execution_count": null, 594 | "metadata": { 595 | "collapsed": true 596 | }, 597 | "outputs": [], 598 | "source": [] 599 | }, 600 | { 601 | "cell_type": "code", 602 | "execution_count": null, 603 | "metadata": { 604 | "collapsed": true 605 | }, 606 | "outputs": [], 607 | "source": [] 608 | }, 609 | { 610 | "cell_type": "code", 611 | "execution_count": null, 612 | "metadata": { 613 | "collapsed": true 614 | }, 615 | "outputs": [], 616 | "source": [] 617 | }, 618 | { 619 | "cell_type": "code", 620 | "execution_count": null, 621 | "metadata": { 622 | "collapsed": true 623 | }, 624 | "outputs": [], 625 | "source": [] 626 | }, 627 | { 628 | "cell_type": "code", 629 | "execution_count": null, 630 | "metadata": { 631 | "collapsed": true 632 | }, 633 | "outputs": [], 634 | "source": [] 635 | }, 636 | { 637 | "cell_type": "code", 638 | "execution_count": null, 639 | "metadata": { 640 | "collapsed": true 641 | }, 642 | "outputs": [], 643 | "source": [] 644 | }, 645 | { 646 | "cell_type": "code", 647 | "execution_count": null, 648 | "metadata": { 649 | "collapsed": true 650 | }, 651 | "outputs": [], 652 | "source": [ 653 | "3.3.1. Introduction and concepts\n", 654 | "\n", 655 | "Images are NumPy’s arrays np.ndarray" 656 | ] 657 | }, 658 | { 659 | "cell_type": "code", 660 | "execution_count": null, 661 | "metadata": { 662 | "collapsed": true 663 | }, 664 | "outputs": [], 665 | "source": [] 666 | }, 667 | { 668 | "cell_type": "code", 669 | "execution_count": null, 670 | "metadata": { 671 | "collapsed": true 672 | }, 673 | "outputs": [], 674 | "source": [] 675 | }, 676 | { 677 | "cell_type": "code", 678 | "execution_count": null, 679 | "metadata": { 680 | "collapsed": true 681 | }, 682 | "outputs": [], 683 | "source": [] 684 | } 685 | ], 686 | "metadata": { 687 | "kernelspec": { 688 | "display_name": "Python 2", 689 | "language": "python", 690 | "name": "python2" 691 | }, 692 | "language_info": { 693 | "codemirror_mode": { 694 | "name": "ipython", 695 | "version": 2 696 | }, 697 | "file_extension": ".py", 698 | "mimetype": "text/x-python", 699 | "name": "python", 700 | "nbconvert_exporter": "python", 701 | "pygments_lexer": "ipython2", 702 | "version": "2.7.11" 703 | } 704 | }, 705 | "nbformat": 4, 706 | "nbformat_minor": 0 707 | } 708 | -------------------------------------------------------------------------------- /3.4. Traits:创建交互对话.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 10, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "%matplotlib inline\n", 12 | "import numpy as np" 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": {}, 18 | "source": [ 19 | ">作者 : *Didrik Pinte*\n", 20 | "\n", 21 | "Traits项目允许你可以向Python项目属性方便的添加验证、初始化、委托、通知和图形化界面。\n", 22 | "\n", 23 | "在这个教程中,我们将研究Traits工具包并且学习如何动态减少你所写的锅炉片代码,进行快速的GUI应用开发,以及理解Enthought工具箱中其他部分的想法。\n", 24 | "\n", 25 | "Traits和Enthought工具箱是基于BSD-style证书的开源项目。\n", 26 | "\n", 27 | "---\n", 28 | "**目标受众**\n", 29 | "\n", 30 | "Python中高级程序员\n", 31 | "---\n", 32 | "\n", 33 | "---\n", 34 | "**要求**\n", 35 | "\n", 36 | "- [wxPython](http://www.wxpython.org/)、[PyQt](https://riverbankcomputing.com/software/pyqt/intro)或[PySide](https://pyside.github.io/docs/pyside/)之一\n", 37 | "- Numpy和Scipy\n", 38 | "- [Enthought工具箱](http://code.enthought.com/projects)\n", 39 | "- 所有需要的软件都可以通过安装[EPD免费版](https://store.enthought.com/)来获得\n", 40 | "---\n", 41 | "\n", 42 | "---\n", 43 | "\n", 44 | "**教程内容**\n", 45 | "- 介绍\n", 46 | "- 例子\n", 47 | "- Traits是什么\n", 48 | " - 初始化\n", 49 | " - 验证\n", 50 | " - 文档\n", 51 | " - 可视化: 打开一个对话框\n", 52 | " - 推迟\n", 53 | " - 通知\n", 54 | " - 一些更高级的特征\n", 55 | " \n", 56 | "## 3.4.1 介绍\n", 57 | "\n", 58 | "Enthought工具箱可以构建用于数据分析、2D绘图和3D可视化的精密应用框架。这些强力可重用的组块是在BSD-style证书下发布的。\n", 59 | "\n", 60 | "Enthought工具箱主要的包是:\n", 61 | "\n", 62 | "- Traits - 基于组块的方式构建我们的应用。\n", 63 | "- Kiva - 2D原生支持基于路径的rendering、affine转化、alpha混合及其它。\n", 64 | "- Enable - 基于对象的2D绘图画布。\n", 65 | "- Chaco - 绘图工具箱,用于构建复杂的交互2D图像。\n", 66 | "- Mayavi -基于VTK的3D科学数据可视化\n", 67 | "- Envisage - 应用插件框架,用于构建脚本化可扩展的应用\n", 68 | "\n", 69 | "![](http://www.scipy-lectures.org/_images/ETS.jpg)\n", 70 | "\n", 71 | "在这篇教程中,我们将关注Traits。\n", 72 | "\n", 73 | "## 3.4.2 例子\n", 74 | "\n", 75 | "在整个这篇教程中,我们将使用基于水资源管理简单案例的一个样例。我们将试着建模一个水坝和水库系统。水库和水坝有下列参数:\n", 76 | "\n", 77 | "- 名称\n", 78 | "- 水库的最小和最大容量 [$hm^3$]\n", 79 | "- 水坝的高度和宽度[$m$]\n", 80 | "- 蓄水面积[$km^2$]\n", 81 | "- 水压头[$m$]\n", 82 | "- 涡轮的动力[$MW$]\n", 83 | "- 最小和最大放水量[$m^3/s$]\n", 84 | "- 涡轮的效率\n", 85 | "\n", 86 | "水库有一个已知的运转情况。一部分是与基于放水量有关的能量产生。估算水力发电机电力生产的简单公式是$P = \\rho hrgk$, 其中\n", 87 | "\n", 88 | "- P 以瓦特为单位的功率, \n", 89 | "- \\rho 是水的密度 ($~1000 kg/m^3$),\n", 90 | "- h 是水的高度,\n", 91 | "- r 是以每秒立方米为单位的流动率,\n", 92 | "- g 重力加速度,9.8 $m/s^2$,\n", 93 | "- k 是效率系数,范围从0到1。\n", 94 | "\n", 95 | "年度的电能生产取决于可用的水供给。在一些设施中,水流率在一年中可能差10倍。\n", 96 | "\n", 97 | "运行状态的第二个部分是蓄水量,蓄水量(storage)依赖于控制和非控制参数:\n", 98 | "\n", 99 | "$storage_{t+1} = storage_t + inflows - release - spillage - irrigation$\n", 100 | "\n", 101 | "---\n", 102 | "本教程中使用的数据不是真实的,可能甚至在现实中没有意义。\n", 103 | "\n", 104 | "---\n", 105 | "\n", 106 | "## 3.4.3 Traits是什么\n", 107 | "\n", 108 | "trait是可以用于常规Python对象属性的类型定义,给出属性的一些额外特性:\n", 109 | "\n", 110 | "- 标准化:\n", 111 | " - 初始化\n", 112 | " - 验证\n", 113 | " - 推迟\n", 114 | "- 通知\n", 115 | "- 可视化\n", 116 | "- 文档\n", 117 | "\n", 118 | "类可以自由混合基于trait的属性与通用Python属性,或者选择允许在这个类中只使用固定的或开放的trait属性集。类定义的Trait属性自动继承自由这个类衍生的其他子类。\n", 119 | "\n", 120 | "创建一个traits类的常用方式是通过扩展**HasTraits**基础类,并且定义类的traits :" 121 | ] 122 | }, 123 | { 124 | "cell_type": "code", 125 | "execution_count": 1, 126 | "metadata": { 127 | "collapsed": true 128 | }, 129 | "outputs": [], 130 | "source": [ 131 | "from traits.api import HasTraits, Str, Float\n", 132 | "\n", 133 | "class Reservoir(HasTraits):\n", 134 | "\n", 135 | " name = Str\n", 136 | " max_storage = Float" 137 | ] 138 | }, 139 | { 140 | "cell_type": "markdown", 141 | "metadata": {}, 142 | "source": [ 143 | "---\n", 144 | "\n", 145 | "对Traits 3.x用户来说\n", 146 | "\n", 147 | "如果使用Traits 3.x, 你需要调整traits包的命名空间:\n", 148 | "\n", 149 | "- traits.api应该为enthought.traits.api\n", 150 | "- traitsui.api应该为enthought.traits.ui.api\n", 151 | "\n", 152 | "---\n", 153 | "\n", 154 | "像这样使用traits类和使用其他Python类一样简单。注意,trait值通过关键词参数传递:" 155 | ] 156 | }, 157 | { 158 | "cell_type": "code", 159 | "execution_count": 2, 160 | "metadata": { 161 | "collapsed": true 162 | }, 163 | "outputs": [], 164 | "source": [ 165 | "reservoir = Reservoir(name='Lac de Vouglans', max_storage=605)" 166 | ] 167 | }, 168 | { 169 | "cell_type": "markdown", 170 | "metadata": {}, 171 | "source": [ 172 | "### 3.4.3.1 初始化\n", 173 | "\n", 174 | "所有的traits都有一个默认值来初始化变量。例如,基础python类型有如下的trait等价物:\n", 175 | "\n", 176 | "\n", 177 | "|Trait|Python类型|内置默认值|\n", 178 | "|-----|-----------|----------------------|\n", 179 | "|Bool|Boolean|False|\n", 180 | "|Complex|Complex number|0+0j|\n", 181 | "|Float|Floating point number|0.0|\n", 182 | "|Int|Plain integer|0|\n", 183 | "|Long|Long integer|0L|\n", 184 | "|Str|String|''|\n", 185 | "|Unicode|Unicode|u''|\n", 186 | "\n", 187 | "存在很多其他预定义的trait类型: Array, Enum, Range, Event, Dict, List, Color, Set, Expression, Code, Callable, Type, Tuple, etc。\n", 188 | "\n", 189 | "自定义默认值可以在代码中定义:" 190 | ] 191 | }, 192 | { 193 | "cell_type": "code", 194 | "execution_count": 3, 195 | "metadata": { 196 | "collapsed": true 197 | }, 198 | "outputs": [], 199 | "source": [ 200 | "from traits.api import HasTraits, Str, Float\n", 201 | "\n", 202 | "class Reservoir(HasTraits):\n", 203 | "\n", 204 | " name = Str\n", 205 | " max_storage = Float(100)\n", 206 | "\n", 207 | "reservoir = Reservoir(name='Lac de Vouglans')" 208 | ] 209 | }, 210 | { 211 | "cell_type": "markdown", 212 | "metadata": {}, 213 | "source": [ 214 | "---\n", 215 | "复杂初始化\n", 216 | "\n", 217 | "当一个trait需要复杂的初始化时,可以实施\\_XXX\\_默认魔法方法。当调用XXX trait时,它会被懒惰的调用。例如:\n", 218 | "\n", 219 | "---" 220 | ] 221 | }, 222 | { 223 | "cell_type": "code", 224 | "execution_count": 4, 225 | "metadata": { 226 | "collapsed": true 227 | }, 228 | "outputs": [], 229 | "source": [ 230 | "def _name_default(self):\n", 231 | " \"\"\" Complex initialisation of the reservoir name. \"\"\"\n", 232 | "\n", 233 | " return 'Undefined'" 234 | ] 235 | }, 236 | { 237 | "cell_type": "markdown", 238 | "metadata": {}, 239 | "source": [ 240 | "### 3.4.3.2 验证\n", 241 | "\n", 242 | "当用户试图设置trait的内容时,每一个trait都会被验证:" 243 | ] 244 | }, 245 | { 246 | "cell_type": "code", 247 | "execution_count": 5, 248 | "metadata": { 249 | "collapsed": false 250 | }, 251 | "outputs": [ 252 | { 253 | "ename": "TraitError", 254 | "evalue": "The 'max_storage' trait of a Reservoir instance must be a float, but a value of '230' was specified.", 255 | "output_type": "error", 256 | "traceback": [ 257 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 258 | "\u001b[0;31mTraitError\u001b[0m Traceback (most recent call last)", 259 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mreservoir\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mReservoir\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'Lac de Vouglans'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmax_storage\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m605\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mreservoir\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmax_storage\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'230'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 260 | "\u001b[0;32m/Library/Python/2.7/site-packages/traits/trait_handlers.pyc\u001b[0m in \u001b[0;36merror\u001b[0;34m(self, object, name, value)\u001b[0m\n\u001b[1;32m 170\u001b[0m \"\"\"\n\u001b[1;32m 171\u001b[0m raise TraitError( object, name, self.full_info( object, name, value ),\n\u001b[0;32m--> 172\u001b[0;31m value )\n\u001b[0m\u001b[1;32m 173\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 174\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mfull_info\u001b[0m \u001b[0;34m(\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mobject\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalue\u001b[0m \u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 261 | "\u001b[0;31mTraitError\u001b[0m: The 'max_storage' trait of a Reservoir instance must be a float, but a value of '230' was specified." 262 | ] 263 | } 264 | ], 265 | "source": [ 266 | "reservoir = Reservoir(name='Lac de Vouglans', max_storage=605)\n", 267 | "\n", 268 | "reservoir.max_storage = '230'" 269 | ] 270 | }, 271 | { 272 | "cell_type": "markdown", 273 | "metadata": {}, 274 | "source": [ 275 | "### 3.4.3.3 文档\n", 276 | "\n", 277 | "从本质上说,所有的traits都提供关于模型自身的文档。创建类的声明方式使它是自解释的:" 278 | ] 279 | }, 280 | { 281 | "cell_type": "code", 282 | "execution_count": 6, 283 | "metadata": { 284 | "collapsed": true 285 | }, 286 | "outputs": [], 287 | "source": [ 288 | "from traits.api import HasTraits, Str, Float\n", 289 | "\n", 290 | "class Reservoir(HasTraits):\n", 291 | "\n", 292 | " name = Str\n", 293 | " max_storage = Float(100)" 294 | ] 295 | }, 296 | { 297 | "cell_type": "markdown", 298 | "metadata": {}, 299 | "source": [ 300 | "trait的**desc**元数据可以用来提供关于trait更多的描述信息:" 301 | ] 302 | }, 303 | { 304 | "cell_type": "code", 305 | "execution_count": 7, 306 | "metadata": { 307 | "collapsed": true 308 | }, 309 | "outputs": [], 310 | "source": [ 311 | "from traits.api import HasTraits, Str, Float\n", 312 | "\n", 313 | "class Reservoir(HasTraits):\n", 314 | "\n", 315 | " name = Str\n", 316 | " max_storage = Float(100, desc='Maximal storage [hm3]')" 317 | ] 318 | }, 319 | { 320 | "cell_type": "markdown", 321 | "metadata": {}, 322 | "source": [ 323 | "现在让我们来定义完整的reservoir类:" 324 | ] 325 | }, 326 | { 327 | "cell_type": "code", 328 | "execution_count": 8, 329 | "metadata": { 330 | "collapsed": false 331 | }, 332 | "outputs": [ 333 | { 334 | "name": "stdout", 335 | "output_type": "stream", 336 | "text": [ 337 | "Releasing 80 m3/s produces 1.3561344e+11 kWh\n" 338 | ] 339 | } 340 | ], 341 | "source": [ 342 | "from traits.api import HasTraits, Str, Float, Range\n", 343 | "\n", 344 | "class Reservoir(HasTraits):\n", 345 | " name = Str\n", 346 | " max_storage = Float(1e6, desc='Maximal storage [hm3]')\n", 347 | " max_release = Float(10, desc='Maximal release [m3/s]')\n", 348 | " head = Float(10, desc='Hydraulic head [m]')\n", 349 | " efficiency = Range(0, 1.)\n", 350 | "\n", 351 | " def energy_production(self, release):\n", 352 | " ''' Returns the energy production [Wh] for the given release [m3/s]\n", 353 | " '''\n", 354 | " power = 1000 * 9.81 * self.head * release * self.efficiency\n", 355 | " return power * 3600\n", 356 | "\n", 357 | "\n", 358 | "if __name__ == '__main__':\n", 359 | " reservoir = Reservoir(\n", 360 | " name = 'Project A',\n", 361 | " max_storage = 30,\n", 362 | " max_release = 100.0,\n", 363 | " head = 60,\n", 364 | " efficiency = 0.8\n", 365 | " )\n", 366 | "\n", 367 | " release = 80\n", 368 | " print 'Releasing {} m3/s produces {} kWh'.format(\n", 369 | " release, reservoir.energy_production(release)\n", 370 | " )" 371 | ] 372 | }, 373 | { 374 | "cell_type": "markdown", 375 | "metadata": {}, 376 | "source": [ 377 | "### 3.4.3.4 可视化: 打开一个对话框\n", 378 | "\n", 379 | "Traits库也关注用户界面,可以弹出一个Reservoir类的默认视图:" 380 | ] 381 | }, 382 | { 383 | "cell_type": "code", 384 | "execution_count": null, 385 | "metadata": { 386 | "collapsed": true 387 | }, 388 | "outputs": [], 389 | "source": [ 390 | "reservoir1 = Reservoir()\n", 391 | "reservoir1.edit_traits()" 392 | ] 393 | }, 394 | { 395 | "cell_type": "markdown", 396 | "metadata": {}, 397 | "source": [ 398 | "![](http://www.scipy-lectures.org/_images/reservoir_default_view.png)\n", 399 | "\n", 400 | "TraitsUI简化了创建用户界面的方式。HasTraits类上的每一个trait都有一个默认的编辑器,将管理trait在屏幕上显示的方式 (即Range trait显示为一个滑块等)。\n", 401 | "\n", 402 | "与Traits声明方式来创建类的相同渠道,TraitsUI提供了声明的界面来构建用户界面代码:" 403 | ] 404 | }, 405 | { 406 | "cell_type": "code", 407 | "execution_count": null, 408 | "metadata": { 409 | "collapsed": true 410 | }, 411 | "outputs": [], 412 | "source": [ 413 | "from traits.api import HasTraits, Str, Float, Range\n", 414 | "from traitsui.api import View\n", 415 | "\n", 416 | "class Reservoir(HasTraits):\n", 417 | " name = Str\n", 418 | " max_storage = Float(1e6, desc='Maximal storage [hm3]')\n", 419 | " max_release = Float(10, desc='Maximal release [m3/s]')\n", 420 | " head = Float(10, desc='Hydraulic head [m]')\n", 421 | " efficiency = Range(0, 1.)\n", 422 | "\n", 423 | " traits_view = View(\n", 424 | " 'name', 'max_storage', 'max_release', 'head', 'efficiency',\n", 425 | " title = 'Reservoir',\n", 426 | " resizable = True,\n", 427 | " )\n", 428 | "\n", 429 | " def energy_production(self, release):\n", 430 | " ''' Returns the energy production [Wh] for the given release [m3/s]\n", 431 | " '''\n", 432 | " power = 1000 * 9.81 * self.head * release * self.efficiency \n", 433 | " return power * 3600\n", 434 | "\n", 435 | "\n", 436 | "if __name__ == '__main__':\n", 437 | " reservoir = Reservoir(\n", 438 | " name = 'Project A',\n", 439 | " max_storage = 30,\n", 440 | " max_release = 100.0,\n", 441 | " head = 60,\n", 442 | " efficiency = 0.8\n", 443 | " )\n", 444 | "\n", 445 | " reservoir.configure_traits()" 446 | ] 447 | }, 448 | { 449 | "cell_type": "markdown", 450 | "metadata": {}, 451 | "source": [ 452 | "![](http://www.scipy-lectures.org/_images/reservoir_view.png)\n", 453 | "\n", 454 | "### 3.4.3.5 推迟\n", 455 | "\n", 456 | "可以将trait定义和它的值推送给另一个对象是Traits的有用的功能。" 457 | ] 458 | }, 459 | { 460 | "cell_type": "code", 461 | "execution_count": null, 462 | "metadata": { 463 | "collapsed": true 464 | }, 465 | "outputs": [], 466 | "source": [ 467 | "from traits.api import HasTraits, Instance, DelegatesTo, Float, Range\n", 468 | "\n", 469 | "from reservoir import Reservoir\n", 470 | "\n", 471 | "class ReservoirState(HasTraits):\n", 472 | " \"\"\"Keeps track of the reservoir state given the initial storage.\n", 473 | " \"\"\"\n", 474 | " reservoir = Instance(Reservoir, ())\n", 475 | " min_storage = Float\n", 476 | " max_storage = DelegatesTo('reservoir')\n", 477 | " min_release = Float\n", 478 | " max_release = DelegatesTo('reservoir')\n", 479 | "\n", 480 | " # state attributes\n", 481 | " storage = Range(low='min_storage', high='max_storage')\n", 482 | "\n", 483 | " # control attributes\n", 484 | " inflows = Float(desc='Inflows [hm3]')\n", 485 | " release = Range(low='min_release', high='max_release')\n", 486 | " spillage = Float(desc='Spillage [hm3]')\n", 487 | "\n", 488 | " def print_state(self):\n", 489 | " print 'Storage\\tRelease\\tInflows\\tSpillage'\n", 490 | " str_format = '\\t'.join(['{:7.2f}'for i in range(4)])\n", 491 | " print str_format.format(self.storage, self.release, self.inflows,\n", 492 | " self.spillage)\n", 493 | " print '-' * 79\n", 494 | "\n", 495 | "\n", 496 | "if __name__ == '__main__':\n", 497 | " projectA = Reservoir(\n", 498 | " name = 'Project A',\n", 499 | " max_storage = 30,\n", 500 | " max_release = 100.0,\n", 501 | " hydraulic_head = 60,\n", 502 | " efficiency = 0.8\n", 503 | " )\n", 504 | "\n", 505 | " state = ReservoirState(reservoir=projectA, storage=10)\n", 506 | " state.release = 90\n", 507 | " state.inflows = 0\n", 508 | " state.print_state()\n", 509 | "\n", 510 | " print 'How do we update the current storage ?'" 511 | ] 512 | }, 513 | { 514 | "cell_type": "markdown", 515 | "metadata": {}, 516 | "source": [ 517 | "特殊的trait允许用魔法\\_xxxx\\_fired方法管理事件和触发器函数:" 518 | ] 519 | }, 520 | { 521 | "cell_type": "code", 522 | "execution_count": null, 523 | "metadata": { 524 | "collapsed": true 525 | }, 526 | "outputs": [], 527 | "source": [ 528 | "from traits.api import HasTraits, Instance, DelegatesTo, Float, Range, Event\n", 529 | "\n", 530 | "from reservoir import Reservoir\n", 531 | "\n", 532 | "class ReservoirState(HasTraits):\n", 533 | " \"\"\"Keeps track of the reservoir state given the initial storage.\n", 534 | "\n", 535 | " For the simplicity of the example, the release is considered in\n", 536 | " hm3/timestep and not in m3/s.\n", 537 | " \"\"\"\n", 538 | " reservoir = Instance(Reservoir, ())\n", 539 | " min_storage = Float\n", 540 | " max_storage = DelegatesTo('reservoir')\n", 541 | " min_release = Float\n", 542 | " max_release = DelegatesTo('reservoir')\n", 543 | "\n", 544 | " # state attributes\n", 545 | " storage = Range(low='min_storage', high='max_storage')\n", 546 | "\n", 547 | " # control attributes\n", 548 | " inflows = Float(desc='Inflows [hm3]')\n", 549 | " release = Range(low='min_release', high='max_release')\n", 550 | " spillage = Float(desc='Spillage [hm3]')\n", 551 | "\n", 552 | " update_storage = Event(desc='Updates the storage to the next time step')\n", 553 | "\n", 554 | " def _update_storage_fired(self):\n", 555 | " # update storage state\n", 556 | " new_storage = self.storage - self.release + self.inflows\n", 557 | " self.storage = min(new_storage, self.max_storage)\n", 558 | " overflow = new_storage - self.max_storage\n", 559 | " self.spillage = max(overflow, 0)\n", 560 | "\n", 561 | " def print_state(self):\n", 562 | " print 'Storage\\tRelease\\tInflows\\tSpillage'\n", 563 | " str_format = '\\t'.join(['{:7.2f}'for i in range(4)])\n", 564 | " print str_format.format(self.storage, self.release, self.inflows,\n", 565 | " self.spillage)\n", 566 | " print '-' * 79\n", 567 | "\n", 568 | "\n", 569 | "if __name__ == '__main__':\n", 570 | " projectA = Reservoir(\n", 571 | " name = 'Project A',\n", 572 | " max_storage = 30,\n", 573 | " max_release = 5.0,\n", 574 | " hydraulic_head = 60,\n", 575 | " efficiency = 0.8\n", 576 | " )\n", 577 | "\n", 578 | " state = ReservoirState(reservoir=projectA, storage=15)\n", 579 | " state.release = 5\n", 580 | " state.inflows = 0\n", 581 | "\n", 582 | " # release the maximum amount of water during 3 time steps\n", 583 | " state.update_storage = True\n", 584 | " state.print_state()\n", 585 | " state.update_storage = True\n", 586 | " state.print_state()\n", 587 | " state.update_storage = True\n", 588 | " state.print_state()" 589 | ] 590 | }, 591 | { 592 | "cell_type": "markdown", 593 | "metadata": {}, 594 | "source": [ 595 | "对象间的依赖可以自动使用trait**Property**完成。**depends_on**属性表示property其他traits的依赖性。当其他traits改变了,property是无效的。此外,Traits为属性使用魔法函数的名字:\n", 596 | "- \\_get\\_XXX 来获得XXX属性的trait\n", 597 | "- \\_set\\_XXX 来设置XXX属性的trait" 598 | ] 599 | }, 600 | { 601 | "cell_type": "code", 602 | "execution_count": null, 603 | "metadata": { 604 | "collapsed": true 605 | }, 606 | "outputs": [], 607 | "source": [ 608 | "from traits.api import HasTraits, Instance, DelegatesTo, Float, Range\n", 609 | "from traits.api import Property\n", 610 | "\n", 611 | "from reservoir import Reservoir\n", 612 | "\n", 613 | "class ReservoirState(HasTraits):\n", 614 | " \"\"\"Keeps track of the reservoir state given the initial storage.\n", 615 | "\n", 616 | " For the simplicity of the example, the release is considered in\n", 617 | " hm3/timestep and not in m3/s.\n", 618 | " \"\"\"\n", 619 | " reservoir = Instance(Reservoir, ())\n", 620 | " max_storage = DelegatesTo('reservoir')\n", 621 | " min_release = Float\n", 622 | " max_release = DelegatesTo('reservoir')\n", 623 | "\n", 624 | " # state attributes\n", 625 | " storage = Property(depends_on='inflows, release')\n", 626 | "\n", 627 | " # control attributes\n", 628 | " inflows = Float(desc='Inflows [hm3]')\n", 629 | " release = Range(low='min_release', high='max_release')\n", 630 | " spillage = Property(\n", 631 | " desc='Spillage [hm3]', depends_on=['storage', 'inflows', 'release']\n", 632 | " )\n", 633 | "\n", 634 | " ### Private traits.\n", 635 | " _storage = Float\n", 636 | "\n", 637 | " ### Traits property implementation.\n", 638 | " def _get_storage(self):\n", 639 | " new_storage = self._storage - self.release + self.inflows\n", 640 | " return min(new_storage, self.max_storage)\n", 641 | "\n", 642 | " def _set_storage(self, storage_value):\n", 643 | " self._storage = storage_value\n", 644 | "\n", 645 | " def _get_spillage(self):\n", 646 | " new_storage = self._storage - self.release + self.inflows\n", 647 | " overflow = new_storage - self.max_storage\n", 648 | " return max(overflow, 0)\n", 649 | "\n", 650 | " def print_state(self):\n", 651 | " print 'Storage\\tRelease\\tInflows\\tSpillage'\n", 652 | " str_format = '\\t'.join(['{:7.2f}'for i in range(4)])\n", 653 | " print str_format.format(self.storage, self.release, self.inflows,\n", 654 | " self.spillage)\n", 655 | " print '-' * 79\n", 656 | "\n", 657 | "if __name__ == '__main__':\n", 658 | " projectA = Reservoir(\n", 659 | " name = 'Project A',\n", 660 | " max_storage = 30,\n", 661 | " max_release = 5,\n", 662 | " hydraulic_head = 60,\n", 663 | " efficiency = 0.8\n", 664 | " )\n", 665 | "\n", 666 | " state = ReservoirState(reservoir=projectA, storage=25)\n", 667 | " state.release = 4\n", 668 | " state.inflows = 0\n", 669 | "\n", 670 | " state.print_state()" 671 | ] 672 | }, 673 | { 674 | "cell_type": "markdown", 675 | "metadata": {}, 676 | "source": [ 677 | "---\n", 678 | "**注意** 缓存属性\n", 679 | "当访问一个输入没有改变的属性时,大量计算或长时间运行的计算会是个问题。@cached_property修饰器可以用来缓存这个值,并且只有在失效时才会重新计算一次他们。\n", 680 | "\n", 681 | "---\n", 682 | "让我们用ReservoirState的例子来扩展TraitsUI介绍:" 683 | ] 684 | }, 685 | { 686 | "cell_type": "code", 687 | "execution_count": null, 688 | "metadata": { 689 | "collapsed": true 690 | }, 691 | "outputs": [], 692 | "source": [ 693 | "from traits.api import HasTraits, Instance, DelegatesTo, Float, Range, Property\n", 694 | "from traitsui.api import View, Item, Group, VGroup\n", 695 | "\n", 696 | "from reservoir import Reservoir\n", 697 | "\n", 698 | "class ReservoirState(HasTraits):\n", 699 | " \"\"\"Keeps track of the reservoir state given the initial storage.\n", 700 | "\n", 701 | " For the simplicity of the example, the release is considered in\n", 702 | " hm3/timestep and not in m3/s.\n", 703 | " \"\"\"\n", 704 | " reservoir = Instance(Reservoir, ())\n", 705 | " name = DelegatesTo('reservoir')\n", 706 | " max_storage = DelegatesTo('reservoir')\n", 707 | " max_release = DelegatesTo('reservoir')\n", 708 | " min_release = Float\n", 709 | "\n", 710 | " # state attributes\n", 711 | " storage = Property(depends_on='inflows, release')\n", 712 | "\n", 713 | " # control attributes\n", 714 | " inflows = Float(desc='Inflows [hm3]')\n", 715 | " release = Range(low='min_release', high='max_release')\n", 716 | " spillage = Property(\n", 717 | " desc='Spillage [hm3]', depends_on=['storage', 'inflows', 'release']\n", 718 | " )\n", 719 | "\n", 720 | " ### Traits view\n", 721 | " traits_view = View(\n", 722 | " Group(\n", 723 | " VGroup(Item('name'), Item('storage'), Item('spillage'),\n", 724 | " label = 'State', style = 'readonly'\n", 725 | " ),\n", 726 | " VGroup(Item('inflows'), Item('release'), label='Control'),\n", 727 | " )\n", 728 | " )\n", 729 | "\n", 730 | " ### Private traits.\n", 731 | " _storage = Float\n", 732 | "\n", 733 | " ### Traits property implementation.\n", 734 | " def _get_storage(self):\n", 735 | " new_storage = self._storage - self.release + self.inflows\n", 736 | " return min(new_storage, self.max_storage)\n", 737 | "\n", 738 | " def _set_storage(self, storage_value):\n", 739 | " self._storage = storage_value\n", 740 | "\n", 741 | " def _get_spillage(self):\n", 742 | " new_storage = self._storage - self.release + self.inflows\n", 743 | " overflow = new_storage - self.max_storage\n", 744 | " return max(overflow, 0)\n", 745 | "\n", 746 | " def print_state(self):\n", 747 | " print 'Storage\\tRelease\\tInflows\\tSpillage'\n", 748 | " str_format = '\\t'.join(['{:7.2f}'for i in range(4)])\n", 749 | " print str_format.format(self.storage, self.release, self.inflows,\n", 750 | " self.spillage)\n", 751 | " print '-' * 79\n", 752 | "\n", 753 | "if __name__ == '__main__':\n", 754 | " projectA = Reservoir(\n", 755 | " name = 'Project A',\n", 756 | " max_storage = 30,\n", 757 | " max_release = 5,\n", 758 | " hydraulic_head = 60,\n", 759 | " efficiency = 0.8\n", 760 | " )\n", 761 | "\n", 762 | " state = ReservoirState(reservoir=projectA, storage=25)\n", 763 | " state.release = 4\n", 764 | " state.inflows = 0\n", 765 | "\n", 766 | " state.print_state()\n", 767 | " state.configure_traits()" 768 | ] 769 | }, 770 | { 771 | "cell_type": "markdown", 772 | "metadata": {}, 773 | "source": [ 774 | "![](http://www.scipy-lectures.org/_images/reservoir_state_view.png)\n", 775 | "\n", 776 | "Some use cases need the delegation mechanism to be broken by the user when setting the value of the trait. The PrototypeFrom trait implements this behaviour." 777 | ] 778 | }, 779 | { 780 | "cell_type": "code", 781 | "execution_count": null, 782 | "metadata": { 783 | "collapsed": true 784 | }, 785 | "outputs": [], 786 | "source": [ 787 | "TraitsUI simplifies the way user interfaces are created. Every trait on a HasTraits class has a default editor that will manage the way the trait is rendered to the screen (e.g. the Range trait is displayed as a slider, etc.).\n", 788 | "In the very same vein as the Traits declarative way of creating classes, TraitsUI provides a declarative interface to build user interfaces code:" 789 | ] 790 | }, 791 | { 792 | "cell_type": "code", 793 | "execution_count": null, 794 | "metadata": { 795 | "collapsed": true 796 | }, 797 | "outputs": [], 798 | "source": [] 799 | }, 800 | { 801 | "cell_type": "code", 802 | "execution_count": null, 803 | "metadata": { 804 | "collapsed": true 805 | }, 806 | "outputs": [], 807 | "source": [] 808 | }, 809 | { 810 | "cell_type": "code", 811 | "execution_count": null, 812 | "metadata": { 813 | "collapsed": true 814 | }, 815 | "outputs": [], 816 | "source": [] 817 | }, 818 | { 819 | "cell_type": "code", 820 | "execution_count": null, 821 | "metadata": { 822 | "collapsed": true 823 | }, 824 | "outputs": [], 825 | "source": [] 826 | }, 827 | { 828 | "cell_type": "code", 829 | "execution_count": null, 830 | "metadata": { 831 | "collapsed": true 832 | }, 833 | "outputs": [], 834 | "source": [] 835 | }, 836 | { 837 | "cell_type": "code", 838 | "execution_count": null, 839 | "metadata": { 840 | "collapsed": true 841 | }, 842 | "outputs": [], 843 | "source": [] 844 | }, 845 | { 846 | "cell_type": "code", 847 | "execution_count": null, 848 | "metadata": { 849 | "collapsed": true 850 | }, 851 | "outputs": [], 852 | "source": [] 853 | }, 854 | { 855 | "cell_type": "code", 856 | "execution_count": null, 857 | "metadata": { 858 | "collapsed": true 859 | }, 860 | "outputs": [], 861 | "source": [] 862 | }, 863 | { 864 | "cell_type": "code", 865 | "execution_count": null, 866 | "metadata": { 867 | "collapsed": true 868 | }, 869 | "outputs": [], 870 | "source": [] 871 | }, 872 | { 873 | "cell_type": "code", 874 | "execution_count": null, 875 | "metadata": { 876 | "collapsed": true 877 | }, 878 | "outputs": [], 879 | "source": [] 880 | }, 881 | { 882 | "cell_type": "code", 883 | "execution_count": null, 884 | "metadata": { 885 | "collapsed": true 886 | }, 887 | "outputs": [], 888 | "source": [] 889 | }, 890 | { 891 | "cell_type": "code", 892 | "execution_count": null, 893 | "metadata": { 894 | "collapsed": true 895 | }, 896 | "outputs": [], 897 | "source": [] 898 | }, 899 | { 900 | "cell_type": "code", 901 | "execution_count": null, 902 | "metadata": { 903 | "collapsed": true 904 | }, 905 | "outputs": [], 906 | "source": [] 907 | }, 908 | { 909 | "cell_type": "code", 910 | "execution_count": null, 911 | "metadata": { 912 | "collapsed": true 913 | }, 914 | "outputs": [], 915 | "source": [] 916 | }, 917 | { 918 | "cell_type": "code", 919 | "execution_count": null, 920 | "metadata": { 921 | "collapsed": true 922 | }, 923 | "outputs": [], 924 | "source": [] 925 | }, 926 | { 927 | "cell_type": "markdown", 928 | "metadata": {}, 929 | "source": [] 930 | } 931 | ], 932 | "metadata": { 933 | "kernelspec": { 934 | "display_name": "Python 2", 935 | "language": "python", 936 | "name": "python2" 937 | }, 938 | "language_info": { 939 | "codemirror_mode": { 940 | "name": "ipython", 941 | "version": 2 942 | }, 943 | "file_extension": ".py", 944 | "mimetype": "text/x-python", 945 | "name": "python", 946 | "nbconvert_exporter": "python", 947 | "pygments_lexer": "ipython2", 948 | "version": "2.7.11" 949 | } 950 | }, 951 | "nbformat": 4, 952 | "nbformat_minor": 0 953 | } 954 | -------------------------------------------------------------------------------- /3.5. 使用Mayavi进行3D作图.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [] 11 | } 12 | ], 13 | "metadata": { 14 | "kernelspec": { 15 | "display_name": "Python 2", 16 | "language": "python", 17 | "name": "python2" 18 | }, 19 | "language_info": { 20 | "codemirror_mode": { 21 | "name": "ipython", 22 | "version": 2 23 | }, 24 | "file_extension": ".py", 25 | "mimetype": "text/x-python", 26 | "name": "python", 27 | "nbconvert_exporter": "python", 28 | "pygments_lexer": "ipython2", 29 | "version": "2.7.11" 30 | } 31 | }, 32 | "nbformat": 4, 33 | "nbformat_minor": 0 34 | } 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Pytho科学计算生态的介绍的中文翻译:http://nbviewer.ipython.org/github/cloga/scipy-lecture-notes_cn/tree/master/ 2 | [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/cloga/scipy-lecture-notes_cn/master) 3 | -------------------------------------------------------------------------------- /data/LICENCE.txt: -------------------------------------------------------------------------------- 1 | The files listed below have licences differing from the original. 2 | 3 | -------------------------------------------------------------------------- 4 | elephant.png, elephant.ppm.gz: 5 | 6 | Copyright (c) Muhammad Mahdi Karim 7 | 8 | Permission is granted to copy, distribute and/or modify this document 9 | under the terms of the GNU Free Documentation License, Version 1.2 10 | only as published by the Free Software Foundation; with no Invariant 11 | Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the 12 | license is included in the section entitled GNU Free Documentation 13 | License. 14 | -------------------------------------------------------------------------------- /data/MV_HFV_012.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloga/scipy-lecture-notes_cn/9e6c6871c797f2f25354938e944ea1121e14ac9e/data/MV_HFV_012.jpg -------------------------------------------------------------------------------- /data/elephant.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloga/scipy-lecture-notes_cn/9e6c6871c797f2f25354938e944ea1121e14ac9e/data/elephant.png -------------------------------------------------------------------------------- /data/max-speeds.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloga/scipy-lecture-notes_cn/9e6c6871c797f2f25354938e944ea1121e14ac9e/data/max-speeds.npy -------------------------------------------------------------------------------- /data/moonlanding.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloga/scipy-lecture-notes_cn/9e6c6871c797f2f25354938e944ea1121e14ac9e/data/moonlanding.png -------------------------------------------------------------------------------- /data/organisms.txt: -------------------------------------------------------------------------------- 1 | ADEME 2 | BRGM 3 | CEA 4 | CEMAGREF 5 | CIRAD 6 | CNES 7 | CNRS 8 | CSTB 9 | IFREMER 10 | INED 11 | INERIS 12 | INRA 13 | INRETS 14 | INRIA 15 | INSERM 16 | IRD 17 | IRSN 18 | LCPC 19 | ONERA 20 | Pasteur 21 | Universites 22 | 23 | -------------------------------------------------------------------------------- /data/populations.txt: -------------------------------------------------------------------------------- 1 | # year hare lynx carrot 2 | 1900 30e3 4e3 48300 3 | 1901 47.2e3 6.1e3 48200 4 | 1902 70.2e3 9.8e3 41500 5 | 1903 77.4e3 35.2e3 38200 6 | 1904 36.3e3 59.4e3 40600 7 | 1905 20.6e3 41.7e3 39800 8 | 1906 18.1e3 19e3 38600 9 | 1907 21.4e3 13e3 42300 10 | 1908 22e3 8.3e3 44500 11 | 1909 25.4e3 9.1e3 42100 12 | 1910 27.1e3 7.4e3 46000 13 | 1911 40.3e3 8e3 46800 14 | 1912 57e3 12.3e3 43800 15 | 1913 76.6e3 19.5e3 40900 16 | 1914 52.3e3 45.7e3 39400 17 | 1915 19.5e3 51.1e3 39000 18 | 1916 11.2e3 29.7e3 36700 19 | 1917 7.6e3 15.8e3 41800 20 | 1918 14.6e3 9.7e3 43300 21 | 1919 16.2e3 10.1e3 41300 22 | 1920 24.7e3 8.6e3 47300 23 | -------------------------------------------------------------------------------- /data/species.txt: -------------------------------------------------------------------------------- 1 | # The species in columns of populations.txt 2 | Hare 3 | Lynx 4 | Carrot 5 | -------------------------------------------------------------------------------- /data/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloga/scipy-lecture-notes_cn/9e6c6871c797f2f25354938e944ea1121e14ac9e/data/test.png -------------------------------------------------------------------------------- /data/test.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloga/scipy-lecture-notes_cn/9e6c6871c797f2f25354938e944ea1121e14ac9e/data/test.wav -------------------------------------------------------------------------------- /data/test2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloga/scipy-lecture-notes_cn/9e6c6871c797f2f25354938e944ea1121e14ac9e/data/test2.png -------------------------------------------------------------------------------- /data/waveform_1.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloga/scipy-lecture-notes_cn/9e6c6871c797f2f25354938e944ea1121e14ac9e/data/waveform_1.npy -------------------------------------------------------------------------------- /data/waveform_2.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloga/scipy-lecture-notes_cn/9e6c6871c797f2f25354938e944ea1121e14ac9e/data/waveform_2.npy -------------------------------------------------------------------------------- /data/women_percentage.txt: -------------------------------------------------------------------------------- 1 | #2006 2005 2004 2003 2002 2001 2 | 38.2 37.1 37.1 38.1 36.7 39.6 3 | 26.9 18.3 24.4 24.3 24.2 20.9 4 | 26.2 26.2 25.6 24.9 24.4 23.6 5 | 27.4 25.7 25.6 23.9 23.0 21.5 6 | 28.0 26.3 24.4 23.5 22.3 21.8 7 | 28.0 27.0 25.2 24.7 24.5 23.4 8 | 31.9 31.0 30.9 31.0 30.6 29.9 9 | 23.5 23.6 23.6 23.6 23.6 22.3 10 | 26.6 26.1 25.7 23.5 24.8 23.8 11 | 52.9 53.6 53.6 56.3 54.7 44.1 12 | 41.0 27.0 27.0 32.0 31.4 17.6 13 | 40.4 39.7 38.7 36.6 35.7 34.4 14 | 32.1 32.3 32.3 32.2 31.7 30.6 15 | 17.4 18.2 19.1 17.9 18.2 18.5 16 | 50.1 49.8 49.9 50.0 50.6 50.6 17 | 25.2 23.5 24.3 24.3 22.3 19.8 18 | 37.8 34.5 34.1 33.3 30.5 30.5 19 | 16.3 15.7 15.6 15.3 15.1 13.1 20 | 14.8 14.9 14.6 13.7 14.1 14 21 | 51.4 50.2 50.0 47.5 49.2 50.9 22 | 33.5 37.1 32.9 32.6 32.3 32.1 23 | 24 | -------------------------------------------------------------------------------- /demo.py: -------------------------------------------------------------------------------- 1 | # For this example to run, you also need the 'ica.py' file 2 | 3 | import numpy as np 4 | from scipy import linalg 5 | 6 | from ica import fastica 7 | 8 | 9 | def test(): 10 | data = np.random.random((5000, 100)) 11 | u, s, v = linalg.svd(data) 12 | pca = np.dot(u[:, :10].T, data) 13 | results = fastica(pca.T, whiten=False) 14 | 15 | if __name__ == '__main__': 16 | test() 17 | -------------------------------------------------------------------------------- /demo.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloga/scipy-lecture-notes_cn/9e6c6871c797f2f25354938e944ea1121e14ac9e/demo.pyc -------------------------------------------------------------------------------- /demo_opt.py: -------------------------------------------------------------------------------- 1 | # For this example to run, you also need the 'ica.py' file 2 | 3 | import numpy as np 4 | from scipy import linalg 5 | 6 | from ica import fastica 7 | 8 | 9 | def test(): 10 | data = np.random.random((5000, 100)) 11 | u, s, v = linalg.svd(data, full_matrices=False) 12 | pca = np.dot(u[:, :10].T, data) 13 | results = fastica(pca.T, whiten=False) 14 | 15 | if __name__ == '__main__': 16 | test() 17 | -------------------------------------------------------------------------------- /demo_opt.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloga/scipy-lecture-notes_cn/9e6c6871c797f2f25354938e944ea1121e14ac9e/demo_opt.pyc -------------------------------------------------------------------------------- /etc/fstab: -------------------------------------------------------------------------------- 1 | fstab -------------------------------------------------------------------------------- /examples/brain_size.csv: -------------------------------------------------------------------------------- 1 | "";"Gender";"FSIQ";"VIQ";"PIQ";"Weight";"Height";"MRI_Count" 2 | "1";"Female";133;132;124;"118";"64.5";816932 3 | "2";"Male";140;150;124;".";"72.5";1001121 4 | "3";"Male";139;123;150;"143";"73.3";1038437 5 | "4";"Male";133;129;128;"172";"68.8";965353 6 | "5";"Female";137;132;134;"147";"65.0";951545 7 | "6";"Female";99;90;110;"146";"69.0";928799 8 | "7";"Female";138;136;131;"138";"64.5";991305 9 | "8";"Female";92;90;98;"175";"66.0";854258 10 | "9";"Male";89;93;84;"134";"66.3";904858 11 | "10";"Male";133;114;147;"172";"68.8";955466 12 | "11";"Female";132;129;124;"118";"64.5";833868 13 | "12";"Male";141;150;128;"151";"70.0";1079549 14 | "13";"Male";135;129;124;"155";"69.0";924059 15 | "14";"Female";140;120;147;"155";"70.5";856472 16 | "15";"Female";96;100;90;"146";"66.0";878897 17 | "16";"Female";83;71;96;"135";"68.0";865363 18 | "17";"Female";132;132;120;"127";"68.5";852244 19 | "18";"Male";100;96;102;"178";"73.5";945088 20 | "19";"Female";101;112;84;"136";"66.3";808020 21 | "20";"Male";80;77;86;"180";"70.0";889083 22 | "21";"Male";83;83;86;".";".";892420 23 | "22";"Male";97;107;84;"186";"76.5";905940 24 | "23";"Female";135;129;134;"122";"62.0";790619 25 | "24";"Male";139;145;128;"132";"68.0";955003 26 | "25";"Female";91;86;102;"114";"63.0";831772 27 | "26";"Male";141;145;131;"171";"72.0";935494 28 | "27";"Female";85;90;84;"140";"68.0";798612 29 | "28";"Male";103;96;110;"187";"77.0";1062462 30 | "29";"Female";77;83;72;"106";"63.0";793549 31 | "30";"Female";130;126;124;"159";"66.5";866662 32 | "31";"Female";133;126;132;"127";"62.5";857782 33 | "32";"Male";144;145;137;"191";"67.0";949589 34 | "33";"Male";103;96;110;"192";"75.5";997925 35 | "34";"Male";90;96;86;"181";"69.0";879987 36 | "35";"Female";83;90;81;"143";"66.5";834344 37 | "36";"Female";133;129;128;"153";"66.5";948066 38 | "37";"Male";140;150;124;"144";"70.5";949395 39 | "38";"Female";88;86;94;"139";"64.5";893983 40 | "39";"Male";81;90;74;"148";"74.0";930016 41 | "40";"Male";89;91;89;"179";"75.5";935863 42 | -------------------------------------------------------------------------------- /examples/iris.csv: -------------------------------------------------------------------------------- 1 | sepal_length,sepal_width,petal_length,petal_width,name 2 | 5.1,3.5,1.4,0.2,setosa 3 | 4.9,3.0,1.4,0.2,setosa 4 | 4.7,3.2,1.3,0.2,setosa 5 | 4.6,3.1,1.5,0.2,setosa 6 | 5.0,3.6,1.4,0.2,setosa 7 | 5.4,3.9,1.7,0.4,setosa 8 | 4.6,3.4,1.4,0.3,setosa 9 | 5.0,3.4,1.5,0.2,setosa 10 | 4.4,2.9,1.4,0.2,setosa 11 | 4.9,3.1,1.5,0.1,setosa 12 | 5.4,3.7,1.5,0.2,setosa 13 | 4.8,3.4,1.6,0.2,setosa 14 | 4.8,3.0,1.4,0.1,setosa 15 | 4.3,3.0,1.1,0.1,setosa 16 | 5.8,4.0,1.2,0.2,setosa 17 | 5.7,4.4,1.5,0.4,setosa 18 | 5.4,3.9,1.3,0.4,setosa 19 | 5.1,3.5,1.4,0.3,setosa 20 | 5.7,3.8,1.7,0.3,setosa 21 | 5.1,3.8,1.5,0.3,setosa 22 | 5.4,3.4,1.7,0.2,setosa 23 | 5.1,3.7,1.5,0.4,setosa 24 | 4.6,3.6,1.0,0.2,setosa 25 | 5.1,3.3,1.7,0.5,setosa 26 | 4.8,3.4,1.9,0.2,setosa 27 | 5.0,3.0,1.6,0.2,setosa 28 | 5.0,3.4,1.6,0.4,setosa 29 | 5.2,3.5,1.5,0.2,setosa 30 | 5.2,3.4,1.4,0.2,setosa 31 | 4.7,3.2,1.6,0.2,setosa 32 | 4.8,3.1,1.6,0.2,setosa 33 | 5.4,3.4,1.5,0.4,setosa 34 | 5.2,4.1,1.5,0.1,setosa 35 | 5.5,4.2,1.4,0.2,setosa 36 | 4.9,3.1,1.5,0.1,setosa 37 | 5.0,3.2,1.2,0.2,setosa 38 | 5.5,3.5,1.3,0.2,setosa 39 | 4.9,3.1,1.5,0.1,setosa 40 | 4.4,3.0,1.3,0.2,setosa 41 | 5.1,3.4,1.5,0.2,setosa 42 | 5.0,3.5,1.3,0.3,setosa 43 | 4.5,2.3,1.3,0.3,setosa 44 | 4.4,3.2,1.3,0.2,setosa 45 | 5.0,3.5,1.6,0.6,setosa 46 | 5.1,3.8,1.9,0.4,setosa 47 | 4.8,3.0,1.4,0.3,setosa 48 | 5.1,3.8,1.6,0.2,setosa 49 | 4.6,3.2,1.4,0.2,setosa 50 | 5.3,3.7,1.5,0.2,setosa 51 | 5.0,3.3,1.4,0.2,setosa 52 | 7.0,3.2,4.7,1.4,versicolor 53 | 6.4,3.2,4.5,1.5,versicolor 54 | 6.9,3.1,4.9,1.5,versicolor 55 | 5.5,2.3,4.0,1.3,versicolor 56 | 6.5,2.8,4.6,1.5,versicolor 57 | 5.7,2.8,4.5,1.3,versicolor 58 | 6.3,3.3,4.7,1.6,versicolor 59 | 4.9,2.4,3.3,1.0,versicolor 60 | 6.6,2.9,4.6,1.3,versicolor 61 | 5.2,2.7,3.9,1.4,versicolor 62 | 5.0,2.0,3.5,1.0,versicolor 63 | 5.9,3.0,4.2,1.5,versicolor 64 | 6.0,2.2,4.0,1.0,versicolor 65 | 6.1,2.9,4.7,1.4,versicolor 66 | 5.6,2.9,3.6,1.3,versicolor 67 | 6.7,3.1,4.4,1.4,versicolor 68 | 5.6,3.0,4.5,1.5,versicolor 69 | 5.8,2.7,4.1,1.0,versicolor 70 | 6.2,2.2,4.5,1.5,versicolor 71 | 5.6,2.5,3.9,1.1,versicolor 72 | 5.9,3.2,4.8,1.8,versicolor 73 | 6.1,2.8,4.0,1.3,versicolor 74 | 6.3,2.5,4.9,1.5,versicolor 75 | 6.1,2.8,4.7,1.2,versicolor 76 | 6.4,2.9,4.3,1.3,versicolor 77 | 6.6,3.0,4.4,1.4,versicolor 78 | 6.8,2.8,4.8,1.4,versicolor 79 | 6.7,3.0,5.0,1.7,versicolor 80 | 6.0,2.9,4.5,1.5,versicolor 81 | 5.7,2.6,3.5,1.0,versicolor 82 | 5.5,2.4,3.8,1.1,versicolor 83 | 5.5,2.4,3.7,1.0,versicolor 84 | 5.8,2.7,3.9,1.2,versicolor 85 | 6.0,2.7,5.1,1.6,versicolor 86 | 5.4,3.0,4.5,1.5,versicolor 87 | 6.0,3.4,4.5,1.6,versicolor 88 | 6.7,3.1,4.7,1.5,versicolor 89 | 6.3,2.3,4.4,1.3,versicolor 90 | 5.6,3.0,4.1,1.3,versicolor 91 | 5.5,2.5,4.0,1.3,versicolor 92 | 5.5,2.6,4.4,1.2,versicolor 93 | 6.1,3.0,4.6,1.4,versicolor 94 | 5.8,2.6,4.0,1.2,versicolor 95 | 5.0,2.3,3.3,1.0,versicolor 96 | 5.6,2.7,4.2,1.3,versicolor 97 | 5.7,3.0,4.2,1.2,versicolor 98 | 5.7,2.9,4.2,1.3,versicolor 99 | 6.2,2.9,4.3,1.3,versicolor 100 | 5.1,2.5,3.0,1.1,versicolor 101 | 5.7,2.8,4.1,1.3,versicolor 102 | 6.3,3.3,6.0,2.5,virginica 103 | 5.8,2.7,5.1,1.9,virginica 104 | 7.1,3.0,5.9,2.1,virginica 105 | 6.3,2.9,5.6,1.8,virginica 106 | 6.5,3.0,5.8,2.2,virginica 107 | 7.6,3.0,6.6,2.1,virginica 108 | 4.9,2.5,4.5,1.7,virginica 109 | 7.3,2.9,6.3,1.8,virginica 110 | 6.7,2.5,5.8,1.8,virginica 111 | 7.2,3.6,6.1,2.5,virginica 112 | 6.5,3.2,5.1,2.0,virginica 113 | 6.4,2.7,5.3,1.9,virginica 114 | 6.8,3.0,5.5,2.1,virginica 115 | 5.7,2.5,5.0,2.0,virginica 116 | 5.8,2.8,5.1,2.4,virginica 117 | 6.4,3.2,5.3,2.3,virginica 118 | 6.5,3.0,5.5,1.8,virginica 119 | 7.7,3.8,6.7,2.2,virginica 120 | 7.7,2.6,6.9,2.3,virginica 121 | 6.0,2.2,5.0,1.5,virginica 122 | 6.9,3.2,5.7,2.3,virginica 123 | 5.6,2.8,4.9,2.0,virginica 124 | 7.7,2.8,6.7,2.0,virginica 125 | 6.3,2.7,4.9,1.8,virginica 126 | 6.7,3.3,5.7,2.1,virginica 127 | 7.2,3.2,6.0,1.8,virginica 128 | 6.2,2.8,4.8,1.8,virginica 129 | 6.1,3.0,4.9,1.8,virginica 130 | 6.4,2.8,5.6,2.1,virginica 131 | 7.2,3.0,5.8,1.6,virginica 132 | 7.4,2.8,6.1,1.9,virginica 133 | 7.9,3.8,6.4,2.0,virginica 134 | 6.4,2.8,5.6,2.2,virginica 135 | 6.3,2.8,5.1,1.5,virginica 136 | 6.1,2.6,5.6,1.4,virginica 137 | 7.7,3.0,6.1,2.3,virginica 138 | 6.3,3.4,5.6,2.4,virginica 139 | 6.4,3.1,5.5,1.8,virginica 140 | 6.0,3.0,4.8,1.8,virginica 141 | 6.9,3.1,5.4,2.1,virginica 142 | 6.7,3.1,5.6,2.4,virginica 143 | 6.9,3.1,5.1,2.3,virginica 144 | 5.8,2.7,5.1,1.9,virginica 145 | 6.8,3.2,5.9,2.3,virginica 146 | 6.7,3.3,5.7,2.5,virginica 147 | 6.7,3.0,5.2,2.3,virginica 148 | 6.3,2.5,5.0,1.9,virginica 149 | 6.5,3.0,5.2,2.0,virginica 150 | 6.2,3.4,5.4,2.3,virginica 151 | 5.9,3.0,5.1,1.8,virginica 152 | -------------------------------------------------------------------------------- /face.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloga/scipy-lecture-notes_cn/9e6c6871c797f2f25354938e944ea1121e14ac9e/face.png -------------------------------------------------------------------------------- /face.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloga/scipy-lecture-notes_cn/9e6c6871c797f2f25354938e944ea1121e14ac9e/face.raw -------------------------------------------------------------------------------- /file.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloga/scipy-lecture-notes_cn/9e6c6871c797f2f25354938e944ea1121e14ac9e/file.mat -------------------------------------------------------------------------------- /foo.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloga/scipy-lecture-notes_cn/9e6c6871c797f2f25354938e944ea1121e14ac9e/foo.txt -------------------------------------------------------------------------------- /ica.py: -------------------------------------------------------------------------------- 1 | # Author: Pierre Lafaye de Micheaux, Stefan van der Walt 2 | # Python FastICA 3 | # License: GPL unless permission obtained otherwise 4 | # Look at algorithms in Tables 8.3 and 8.4 page 196 in the book: Independent Component Analysis, by Aapo et al. 5 | 6 | import numpy as np 7 | import types 8 | 9 | 10 | __all__ = ['fastica'] 11 | 12 | 13 | def _gs_decorrelation(w, W, j): 14 | """ Gram-Schmidt-like decorrelation. """ 15 | t = np.zeros_like(w) 16 | for u in range(j): 17 | t = t + np.dot(w, W[u]) * W[u] 18 | w -= t 19 | return w 20 | 21 | 22 | def _ica_def(X, tol, g, gprime, fun_args, maxit, w_init): 23 | """Deflationary FastICA using fun approx to neg-entropy function 24 | 25 | Used internally by FastICA. 26 | """ 27 | 28 | n_comp = w_init.shape[0] 29 | W = np.zeros((n_comp, n_comp), dtype=float) 30 | 31 | # j is the index of the extracted component 32 | for j in range(n_comp): 33 | w = w_init[j, :].copy() 34 | w /= np.sqrt((w**2).sum()) 35 | 36 | n_iterations = 0 37 | # we set lim to tol+1 to be sure to enter at least once in next while 38 | lim = tol + 1 39 | while ((lim > tol) & (n_iterations < (maxit-1))): 40 | wtx = np.dot(w.T, X) 41 | gwtx = g(wtx, fun_args) 42 | g_wtx = gprime(wtx, fun_args) 43 | w1 = (X * gwtx).mean(axis=1) - g_wtx.mean() * w 44 | 45 | _gs_decorrelation(w1, W, j) 46 | 47 | w1 /= np.sqrt((w1**2).sum()) 48 | 49 | lim = np.abs(np.abs((w1 * w).sum()) - 1) 50 | w = w1 51 | n_iterations = n_iterations + 1 52 | 53 | W[j, :] = w 54 | 55 | return W 56 | 57 | 58 | def _sym_decorrelation(W): 59 | """ Symmetric decorrelation """ 60 | K = np.dot(W, W.T) 61 | s, u = np.linalg.eigh(K) 62 | # u (resp. s) contains the eigenvectors (resp. square roots of 63 | # the eigenvalues) of W * W.T 64 | u, W = [np.asmatrix(e) for e in (u, W)] 65 | W = (u * np.diag(1.0/np.sqrt(s)) * u.T) * W # W = (W * W.T) ^{-1/2} * W 66 | return W 67 | 68 | 69 | def _ica_par(X, tol, g, gprime, fun_args, maxit, w_init): 70 | """Parallel FastICA. 71 | 72 | Used internally by FastICA. 73 | 74 | """ 75 | n,p = X.shape 76 | 77 | W = _sym_decorrelation(w_init) 78 | 79 | # we set lim to tol+1 to be sure to enter at least once in next while 80 | lim = tol + 1 81 | it = 0 82 | while ((lim > tol) and (it < (maxit-1))): 83 | wtx = np.dot(W, X).A # .A transforms to array type 84 | gwtx = g(wtx, fun_args) 85 | g_wtx = gprime(wtx, fun_args) 86 | W1 = np.dot(gwtx, X.T)/float(p) - np.dot(np.diag(g_wtx.mean(axis=1)), W) 87 | 88 | W1 = _sym_decorrelation(W1) 89 | 90 | lim = max(abs(abs(np.diag(np.dot(W1, W.T))) - 1)) 91 | W = W1 92 | it = it + 1 93 | 94 | return W 95 | 96 | 97 | def fastica(X, n_comp=None, 98 | algorithm="parallel", whiten=True, fun="logcosh", fun_prime='', 99 | fun_args={}, maxit=200, tol=1e-04, w_init=None): 100 | """Perform Fast Independent Component Analysis. 101 | 102 | Parameters 103 | ---------- 104 | X : (n,p) array 105 | Array with n observations (statistical units) measured on p variables. 106 | n_comp : int, optional 107 | Number of components to extract. If None no dimension reduction 108 | is performed. 109 | algorithm : {'parallel','deflation'} 110 | Apply an parallel or deflational FASTICA algorithm. 111 | whiten: boolean, optional 112 | If true perform an initial whitening of the data. Do not set to 113 | false unless the data is already white, as you will get incorrect 114 | results. 115 | If whiten is true, the data is assumed to have already been 116 | preprocessed: it should be centered, normed and white. 117 | fun : String or Function 118 | The functional form of the G function used in the 119 | approximation to neg-entropy. Could be either 'logcosh', 'exp', 120 | or 'cube'. 121 | You can also provide your own function but in this case, its 122 | derivative should be provided via argument fun_prime 123 | fun_prime : Empty string ('') or Function 124 | See fun. 125 | fun_args : Optional dictionnary 126 | If empty and if fun='logcosh', fun_args will take value 127 | {'alpha' : 1.0} 128 | maxit : int 129 | Maximum number of iterations to perform 130 | tol : float 131 | A positive scalar giving the tolerance at which the 132 | un-mixing matrix is considered to have converged 133 | w_init : (n_comp,n_comp) array 134 | Initial un-mixing array of dimension (n.comp,n.comp). 135 | If None (default) then an array of normal r.v.'s is used 136 | source_only: if True, only the sources matrix is returned 137 | 138 | Results 139 | ------- 140 | K : (p,n_comp) array 141 | pre-whitening matrix that projects data onto th first n.comp 142 | principal components. Returned only if whiten is True 143 | W : (n_comp,n_comp) array 144 | estimated un-mixing matrix 145 | The mixing matrix can be obtained by:: 146 | w = np.asmatrix(W) * K.T 147 | A = w.T * (w * w.T).I 148 | S : (n,n_comp) array 149 | estimated source matrix 150 | 151 | Examples 152 | -------- 153 | 154 | >>> X = np.array( 155 | [[5.,1.4,1.9,0], \ 156 | [2,5.4,8.,1.1], \ 157 | [3,6.4,9,1.2]]) 158 | >>> w_init = np.array([[1,4],[7,2]]) 159 | >>> n_comp = 2 160 | >>> k, W, S = fastica(X, n_comp, algorithm='parallel', w_init=w_init) 161 | >>> print S 162 | [[-0.02387286 -1.41401205] 163 | [ 1.23650679 0.68633152] 164 | [-1.21263393 0.72768053]] 165 | 166 | Notes 167 | ----- 168 | 169 | The data matrix X is considered to be a linear combination of 170 | non-Gaussian (independent) components i.e. X = SA where columns of S 171 | contain the independent components and A is a linear mixing 172 | matrix. In short ICA attempts to `un-mix' the data by estimating an 173 | un-mixing matrix W where XW = S. 174 | 175 | Implemented using FastICA: 176 | 177 | A. Hyvarinen and E. Oja, Independent Component Analysis: 178 | Algorithms and Applications, Neural Networks, 13(4-5), 2000, 179 | pp. 411-430 180 | 181 | """ 182 | algorithm_funcs = {'parallel': _ica_par, 183 | 'deflation': _ica_def} 184 | 185 | alpha = fun_args.get('alpha',1.0) 186 | if (alpha < 1) or (alpha > 2): 187 | raise ValueError("alpha must be in [1,2]") 188 | 189 | if type(fun) is types.StringType: 190 | # Some standard nonlinear functions 191 | if fun == 'logcosh': 192 | def g(x, fun_args): 193 | alpha = fun_args.get('alpha', 1.0) 194 | return np.tanh(alpha * x) 195 | def gprime(x, fun_args): 196 | alpha = fun_args.get('alpha', 1.0) 197 | return alpha * (1 - (np.tanh(alpha * x))**2) 198 | elif fun == 'exp': 199 | def g(x, fun_args): 200 | return x * np.exp(-(x**2)/2) 201 | def gprime(x, fun_args): 202 | return (1 - x**2) * np.exp(-(x**2)/2) 203 | elif fun == 'cube': 204 | def g(x, fun_args): 205 | return x**3 206 | def gprime(x, fun_args): 207 | return 3*x**2 208 | else: 209 | raise ValueError( 210 | 'fun argument should be one of logcosh, exp or cube') 211 | elif type(fun) is not types.FunctionType: 212 | raise ValueError('fun argument should be either a string ' 213 | '(one of logcosh, exp or cube) or a function') 214 | else: 215 | def g(x, fun_args): 216 | return fun(x, **fun_args) 217 | def gprime(x, fun_args): 218 | return fun_prime(x, **fun_args) 219 | 220 | n, p = X.shape 221 | 222 | if n_comp is None: 223 | n_comp = min(n, p) 224 | if (n_comp > min(n, p)): 225 | n_comp = min(n, p) 226 | print("n_comp is too large: it will be set to %s" % n_comp) 227 | 228 | 229 | if whiten: 230 | # Centering the columns (ie the variables) 231 | X = X - X.mean(axis=0) 232 | 233 | # Whitening and preprocessing by PCA 234 | _, d, v = np.linalg.svd(X, full_matrices=False) 235 | del _ 236 | # XXX: Maybe we could provide a mean to estimate n_comp if it has not 237 | # been provided ??? So that we do not have to perform another PCA 238 | # before calling fastica ??? 239 | K = (v*(np.sqrt(n)/d)[:, np.newaxis])[:n_comp] # see (6.33) p.140 240 | del v, d 241 | X1 = np.dot(K, X.T) # see (13.6) p.267 Here X1 is white and data in X has been projected onto a subspace by PCA 242 | else: 243 | X1 = X.T 244 | 245 | if w_init is None: 246 | w_init = np.random.normal(size=(n_comp, n_comp)) 247 | else: 248 | w_init = np.asarray(w_init) 249 | if w_init.shape != (n_comp,n_comp): 250 | raise ValueError("w_init has invalid shape -- should be %(shape)s" 251 | % {'shape': (n_comp,n_comp)}) 252 | 253 | kwargs = {'tol': tol, 254 | 'g': g, 255 | 'gprime': gprime, 256 | 'fun_args': fun_args, 257 | 'maxit': maxit, 258 | 'w_init': w_init} 259 | 260 | func = algorithm_funcs.get(algorithm, 'parallel') 261 | 262 | W = func(X1, **kwargs) 263 | del X1 264 | 265 | if whiten: 266 | S = np.dot(np.asmatrix(W) * K, X.T) 267 | return [np.asarray(e.T) for e in (K, W, S)] 268 | else: 269 | S = np.dot(W, X.T) 270 | return [np.asarray(e.T) for e in (W, S)] 271 | 272 | 273 | -------------------------------------------------------------------------------- /ica.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloga/scipy-lecture-notes_cn/9e6c6871c797f2f25354938e944ea1121e14ac9e/ica.pyc -------------------------------------------------------------------------------- /index_error.py: -------------------------------------------------------------------------------- 1 | """Small snippet to raise an IndexError.""" 2 | 3 | def index_error(): 4 | lst = list('foobar') 5 | print lst[len(lst)] 6 | 7 | if __name__ == '__main__': 8 | index_error() 9 | 10 | -------------------------------------------------------------------------------- /local_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloga/scipy-lecture-notes_cn/9e6c6871c797f2f25354938e944ea1121e14ac9e/local_logo.png -------------------------------------------------------------------------------- /mandelbrot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloga/scipy-lecture-notes_cn/9e6c6871c797f2f25354938e944ea1121e14ac9e/mandelbrot.png -------------------------------------------------------------------------------- /plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloga/scipy-lecture-notes_cn/9e6c6871c797f2f25354938e944ea1121e14ac9e/plot.png -------------------------------------------------------------------------------- /pop.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloga/scipy-lecture-notes_cn/9e6c6871c797f2f25354938e944ea1121e14ac9e/pop.npy -------------------------------------------------------------------------------- /pop2.txt: -------------------------------------------------------------------------------- 1 | 1.900000000000000000e+03 3.000000000000000000e+04 4.000000000000000000e+03 4.830000000000000000e+04 2 | 1.901000000000000000e+03 4.720000000000000000e+04 6.100000000000000000e+03 4.820000000000000000e+04 3 | 1.902000000000000000e+03 7.020000000000000000e+04 9.800000000000000000e+03 4.150000000000000000e+04 4 | 1.903000000000000000e+03 7.740000000000000000e+04 3.520000000000000000e+04 3.820000000000000000e+04 5 | 1.904000000000000000e+03 3.630000000000000000e+04 5.940000000000000000e+04 4.060000000000000000e+04 6 | 1.905000000000000000e+03 2.060000000000000000e+04 4.170000000000000000e+04 3.980000000000000000e+04 7 | 1.906000000000000000e+03 1.810000000000000000e+04 1.900000000000000000e+04 3.860000000000000000e+04 8 | 1.907000000000000000e+03 2.140000000000000000e+04 1.300000000000000000e+04 4.230000000000000000e+04 9 | 1.908000000000000000e+03 2.200000000000000000e+04 8.300000000000000000e+03 4.450000000000000000e+04 10 | 1.909000000000000000e+03 2.540000000000000000e+04 9.100000000000000000e+03 4.210000000000000000e+04 11 | 1.910000000000000000e+03 2.710000000000000000e+04 7.400000000000000000e+03 4.600000000000000000e+04 12 | 1.911000000000000000e+03 4.030000000000000000e+04 8.000000000000000000e+03 4.680000000000000000e+04 13 | 1.912000000000000000e+03 5.700000000000000000e+04 1.230000000000000000e+04 4.380000000000000000e+04 14 | 1.913000000000000000e+03 7.660000000000000000e+04 1.950000000000000000e+04 4.090000000000000000e+04 15 | 1.914000000000000000e+03 5.230000000000000000e+04 4.570000000000000000e+04 3.940000000000000000e+04 16 | 1.915000000000000000e+03 1.950000000000000000e+04 5.110000000000000000e+04 3.900000000000000000e+04 17 | 1.916000000000000000e+03 1.120000000000000000e+04 2.970000000000000000e+04 3.670000000000000000e+04 18 | 1.917000000000000000e+03 7.600000000000000000e+03 1.580000000000000000e+04 4.180000000000000000e+04 19 | 1.918000000000000000e+03 1.460000000000000000e+04 9.700000000000000000e+03 4.330000000000000000e+04 20 | 1.919000000000000000e+03 1.620000000000000000e+04 1.010000000000000000e+04 4.130000000000000000e+04 21 | 1.920000000000000000e+03 2.470000000000000000e+04 8.600000000000000000e+03 4.730000000000000000e+04 22 | -------------------------------------------------------------------------------- /red_elephant.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloga/scipy-lecture-notes_cn/9e6c6871c797f2f25354938e944ea1121e14ac9e/red_elephant.png -------------------------------------------------------------------------------- /tiny_elephant.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloga/scipy-lecture-notes_cn/9e6c6871c797f2f25354938e944ea1121e14ac9e/tiny_elephant.png -------------------------------------------------------------------------------- /untitled.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloga/scipy-lecture-notes_cn/9e6c6871c797f2f25354938e944ea1121e14ac9e/untitled.txt -------------------------------------------------------------------------------- /wages.txt: -------------------------------------------------------------------------------- 1 | Determinants of Wages from the 1985 Current Population Survey 2 | 3 | Summary: 4 | The Current Population Survey (CPS) is used to supplement census information between census years. These data consist of a random sample of 534 persons from the CPS, with information on wages and other characteristics of the workers, including sex, number of years of education, years of work experience, occupational status, region of residence and union membership. We wish to determine (i) whether wages are related to these characteristics and (ii) whether there is a gender gap in wages. 5 | Based on residual plots, wages were log-transformed to stabilize the variance. Age and work experience were almost perfectly correlated (r=.98). Multiple regression of log wages against sex, age, years of education, work experience, union membership, southern residence, and occupational status showed that these covariates were related to wages (pooled F test, p < .0001). The effect of age was not significant after controlling for experience. Standardized residual plots showed no patterns, except for one large outlier with lower wages than expected. This was a male, with 22 years of experience and 12 years of education, in a management position, who lived in the north and was not a union member. Removing this person from the analysis did not substantially change the results, so that the final model included the entire sample. 6 | Adjusting for all other variables in the model, females earned 81% (75%, 88%) the wages of males (p < .0001). Wages increased 41% (28%, 56%) for every 5 additional years of education (p < .0001). They increased by 11% (7%, 14%) for every additional 10 years of experience (p < .0001). Union members were paid 23% (12%, 36%) more than non-union members (p < .0001). Northerns were paid 11% (2%, 20%) more than southerns (p =.016). Management and professional positions were paid most, and service and clerical positions were paid least (pooled F-test, p < .0001). Overall variance explained was R2 = .35. 7 | In summary, many factors describe the variations in wages: occupational status, years of experience, years of education, sex, union membership and region of residence. However, despite adjustment for all factors that were available, there still appeared to be a gender gap in wages. There is no readily available explanation for this gender gap. 8 | 9 | Authorization: Public Domain 10 | 11 | Reference: Berndt, ER. The Practice of Econometrics. 1991. NY: Addison-Wesley. 12 | 13 | Description: The datafile contains 534 observations on 11 variables sampled from the Current Population Survey of 1985. This data set demonstrates multiple regression, confounding, transformations, multicollinearity, categorical variables, ANOVA, pooled tests of significance, interactions and model building strategies. 14 | 15 | Variable names in order from left to right: 16 | EDUCATION: Number of years of education. 17 | SOUTH: Indicator variable for Southern Region (1=Person lives in South, 0=Person lives elsewhere). 18 | SEX: Indicator variable for sex (1=Female, 0=Male). 19 | EXPERIENCE: Number of years of work experience. 20 | UNION: Indicator variable for union membership (1=Union member, 0=Not union member). 21 | WAGE: Wage (dollars per hour). 22 | AGE: Age (years). 23 | RACE: Race (1=Other, 2=Hispanic, 3=White). 24 | OCCUPATION: Occupational category (1=Management, 2=Sales, 3=Clerical, 4=Service, 5=Professional, 6=Other). 25 | SECTOR: Sector (0=Other, 1=Manufacturing, 2=Construction). 26 | MARR: Marital Status (0=Unmarried, 1=Married) 27 | 28 | 8 0 1 21 0 5.1 35 2 6 1 1 29 | 9 0 1 42 0 4.95 57 3 6 1 1 30 | 12 0 0 1 0 6.67 19 3 6 1 0 31 | 12 0 0 4 0 4 22 3 6 0 0 32 | 12 0 0 17 0 7.5 35 3 6 0 1 33 | 13 0 0 9 1 13.07 28 3 6 0 0 34 | 10 1 0 27 0 4.45 43 3 6 0 0 35 | 12 0 0 9 0 19.47 27 3 6 0 0 36 | 16 0 0 11 0 13.28 33 3 6 1 1 37 | 12 0 0 9 0 8.75 27 3 6 0 0 38 | 12 0 0 17 1 11.35 35 3 6 0 1 39 | 12 0 0 19 1 11.5 37 3 6 1 0 40 | 8 1 0 27 0 6.5 41 3 6 0 1 41 | 9 1 0 30 1 6.25 45 3 6 0 0 42 | 9 1 0 29 0 19.98 44 3 6 0 1 43 | 12 0 0 37 0 7.3 55 3 6 2 1 44 | 7 1 0 44 0 8 57 3 6 0 1 45 | 12 0 0 26 1 22.2 44 3 6 1 1 46 | 11 0 0 16 0 3.65 33 3 6 0 0 47 | 12 0 0 33 0 20.55 51 3 6 0 1 48 | 12 0 1 16 1 5.71 34 3 6 1 1 49 | 7 0 0 42 1 7 55 1 6 1 1 50 | 12 0 0 9 0 3.75 27 3 6 0 0 51 | 11 1 0 14 0 4.5 31 1 6 0 1 52 | 12 0 0 23 0 9.56 41 3 6 0 1 53 | 6 1 0 45 0 5.75 57 3 6 1 1 54 | 12 0 0 8 0 9.36 26 3 6 1 1 55 | 10 0 0 30 0 6.5 46 3 6 0 1 56 | 12 0 1 8 0 3.35 26 3 6 1 1 57 | 12 0 0 8 0 4.75 26 3 6 0 1 58 | 14 0 0 13 0 8.9 33 3 6 0 0 59 | 12 1 1 46 0 4 64 3 6 0 0 60 | 8 0 0 19 0 4.7 33 3 6 0 1 61 | 17 1 1 1 0 5 24 3 6 0 0 62 | 12 0 0 19 0 9.25 37 3 6 1 0 63 | 12 0 0 36 0 10.67 54 1 6 0 0 64 | 12 1 0 20 0 7.61 38 1 6 2 1 65 | 12 0 0 35 1 10 53 1 6 2 1 66 | 12 0 0 3 0 7.5 21 3 6 0 0 67 | 14 1 0 10 0 12.2 30 3 6 1 1 68 | 12 0 0 0 0 3.35 18 3 6 0 0 69 | 14 1 0 14 1 11 34 3 6 1 1 70 | 12 0 0 14 0 12 32 3 6 1 1 71 | 9 0 1 16 0 4.85 31 3 6 1 1 72 | 13 1 0 8 0 4.3 27 3 6 2 0 73 | 7 1 1 15 0 6 28 3 6 1 1 74 | 16 0 0 12 0 15 34 3 6 1 1 75 | 10 1 0 13 0 4.85 29 3 6 0 0 76 | 8 0 0 33 1 9 47 3 6 0 1 77 | 12 0 0 9 0 6.36 27 3 6 1 1 78 | 12 0 0 7 0 9.15 25 3 6 0 1 79 | 16 0 0 13 1 11 35 3 6 1 1 80 | 12 0 1 7 0 4.5 25 3 6 1 1 81 | 12 0 1 16 0 4.8 34 3 6 1 1 82 | 13 0 0 0 0 4 19 3 6 0 0 83 | 12 0 1 11 0 5.5 29 3 6 1 0 84 | 13 0 0 17 0 8.4 36 3 6 1 0 85 | 10 0 0 13 0 6.75 29 3 6 1 1 86 | 12 0 0 22 1 10 40 1 6 1 0 87 | 12 0 1 28 0 5 46 3 6 1 1 88 | 11 0 0 17 0 6.5 34 3 6 0 0 89 | 12 0 0 24 1 10.75 42 3 6 2 1 90 | 3 1 0 55 0 7 64 2 6 1 1 91 | 12 1 0 3 0 11.43 21 3 6 2 0 92 | 12 0 0 6 1 4 24 1 6 1 0 93 | 10 0 0 27 0 9 43 3 6 2 1 94 | 12 1 0 19 1 13 37 1 6 1 1 95 | 12 0 0 19 1 12.22 37 3 6 2 1 96 | 12 0 1 38 0 6.28 56 3 6 1 1 97 | 10 1 0 41 1 6.75 57 1 6 1 1 98 | 11 1 0 3 0 3.35 20 1 6 1 0 99 | 14 0 0 20 1 16 40 3 6 0 1 100 | 10 0 0 15 0 5.25 31 3 6 0 1 101 | 8 1 0 8 0 3.5 22 2 6 1 1 102 | 8 1 1 39 0 4.22 53 3 6 1 1 103 | 6 0 1 43 1 3 55 2 6 1 1 104 | 11 1 1 25 1 4 42 3 6 1 1 105 | 12 0 0 11 1 10 29 3 6 0 1 106 | 12 0 0 12 0 5 30 1 6 0 1 107 | 12 1 0 35 1 16 53 3 6 1 1 108 | 14 0 0 14 0 13.98 34 3 6 0 0 109 | 12 0 0 16 1 13.26 34 3 6 0 1 110 | 10 0 1 44 1 6.1 60 3 6 1 0 111 | 16 1 1 13 0 3.75 35 3 6 0 0 112 | 13 0 0 8 1 9 27 1 6 1 0 113 | 12 0 0 13 0 9.45 31 3 6 1 0 114 | 11 0 0 18 1 5.5 35 3 6 0 1 115 | 12 0 1 18 0 8.93 36 3 6 0 1 116 | 12 1 1 6 0 6.25 24 3 6 0 0 117 | 11 1 0 37 1 9.75 54 3 6 1 1 118 | 12 1 0 2 0 6.73 20 3 6 1 1 119 | 12 0 0 23 0 7.78 41 3 6 1 1 120 | 12 0 0 1 0 2.85 19 3 6 0 0 121 | 12 1 1 10 0 3.35 28 1 6 1 1 122 | 12 0 0 23 0 19.98 41 3 6 1 1 123 | 12 0 0 8 1 8.5 26 1 6 0 1 124 | 15 0 1 9 0 9.75 30 3 6 1 1 125 | 12 0 0 33 1 15 51 3 6 2 1 126 | 12 0 1 19 0 8 37 3 6 1 1 127 | 13 0 0 14 0 11.25 33 3 6 0 1 128 | 11 0 0 13 1 14 30 3 6 0 1 129 | 10 0 0 12 0 10 28 3 6 2 1 130 | 12 0 0 8 0 6.5 26 3 6 0 0 131 | 12 0 0 23 0 9.83 41 3 6 1 1 132 | 14 0 1 13 0 18.5 33 3 6 1 0 133 | 12 1 0 9 0 12.5 27 3 6 0 1 134 | 14 0 0 21 1 26 41 3 6 0 1 135 | 5 1 0 44 0 14 55 3 6 2 1 136 | 12 0 0 4 1 10.5 22 3 6 0 1 137 | 8 0 0 42 0 11 56 3 6 1 1 138 | 13 0 0 10 1 12.47 29 3 6 0 1 139 | 12 0 0 11 0 12.5 29 3 6 2 0 140 | 12 0 0 40 1 15 58 3 6 2 1 141 | 12 0 0 8 0 6 26 3 6 2 0 142 | 11 1 0 29 0 9.5 46 3 6 2 1 143 | 16 0 0 3 1 5 25 3 6 0 0 144 | 11 0 0 11 0 3.75 28 3 6 2 0 145 | 12 0 0 12 1 12.57 30 3 6 0 1 146 | 8 0 1 22 0 6.88 36 2 6 0 1 147 | 12 0 0 12 0 5.5 30 3 6 0 1 148 | 12 0 0 7 1 7 25 3 6 0 1 149 | 12 0 1 15 0 4.5 33 3 6 1 0 150 | 12 0 0 28 0 6.5 46 3 6 0 1 151 | 12 1 0 20 1 12 38 3 6 1 1 152 | 12 1 0 6 0 5 24 3 6 2 0 153 | 12 1 0 5 0 6.5 23 3 6 1 0 154 | 9 1 1 30 0 6.8 45 3 6 1 1 155 | 13 0 0 18 0 8.75 37 3 6 0 1 156 | 12 1 1 6 0 3.75 24 1 6 1 1 157 | 12 1 0 16 0 4.5 34 2 6 0 0 158 | 12 1 0 1 1 6 19 2 6 0 0 159 | 12 0 0 3 0 5.5 21 3 6 1 0 160 | 12 0 0 8 0 13 26 3 6 0 1 161 | 14 0 0 2 0 5.65 22 3 6 1 0 162 | 9 0 0 16 0 4.8 31 1 6 1 0 163 | 10 1 0 9 0 7 25 3 6 2 1 164 | 12 0 0 2 0 5.25 20 3 6 0 0 165 | 7 1 0 43 0 3.35 56 3 6 1 1 166 | 9 0 0 38 0 8.5 53 3 6 1 1 167 | 12 0 0 9 0 6 27 3 6 0 1 168 | 12 1 0 12 0 6.75 30 3 6 0 1 169 | 12 0 0 18 0 8.89 36 3 6 1 1 170 | 11 0 0 15 1 14.21 32 3 6 1 0 171 | 11 1 0 28 1 10.78 45 1 6 2 1 172 | 10 1 0 27 1 8.9 43 3 6 2 1 173 | 12 1 0 38 0 7.5 56 3 6 0 1 174 | 12 0 1 3 0 4.5 21 3 6 1 0 175 | 12 0 0 41 1 11.25 59 3 6 0 1 176 | 12 1 0 16 1 13.45 34 3 6 0 1 177 | 13 1 0 7 0 6 26 3 6 1 1 178 | 6 1 1 33 0 4.62 45 1 6 1 0 179 | 14 0 0 25 0 10.58 45 3 6 1 1 180 | 12 1 0 5 0 5 23 3 6 0 1 181 | 14 1 0 17 0 8.2 37 1 6 0 0 182 | 12 1 0 1 0 6.25 19 3 6 0 0 183 | 12 0 0 13 0 8.5 31 3 6 1 1 184 | 16 0 0 18 0 24.98 40 3 1 0 1 185 | 14 1 0 21 0 16.65 41 3 1 0 1 186 | 14 0 0 2 0 6.25 22 3 1 0 0 187 | 12 1 1 4 0 4.55 22 2 1 0 0 188 | 12 1 1 30 0 11.25 48 2 1 0 1 189 | 13 0 0 32 0 21.25 51 3 1 0 0 190 | 17 0 1 13 0 12.65 36 3 1 0 1 191 | 12 0 0 17 0 7.5 35 3 1 0 0 192 | 14 0 1 26 0 10.25 46 3 1 0 1 193 | 16 0 0 9 0 3.35 31 3 1 0 0 194 | 16 0 0 8 0 13.45 30 1 1 0 0 195 | 15 0 0 1 1 4.84 22 3 1 0 1 196 | 17 1 0 32 0 26.29 55 3 1 0 1 197 | 12 0 1 24 0 6.58 42 3 1 0 1 198 | 14 0 1 1 0 44.5 21 3 1 0 0 199 | 12 0 0 42 0 15 60 3 1 1 1 200 | 16 0 1 3 0 11.25 25 1 1 1 0 201 | 12 0 1 32 0 7 50 3 1 0 1 202 | 14 0 0 22 0 10 42 1 1 0 0 203 | 16 0 0 18 0 14.53 40 3 1 0 1 204 | 18 0 1 19 0 20 43 3 1 0 1 205 | 15 0 0 12 0 22.5 33 3 1 0 1 206 | 12 0 1 42 0 3.64 60 3 1 0 1 207 | 12 1 0 34 0 10.62 52 3 1 0 1 208 | 18 0 0 29 0 24.98 53 3 1 0 1 209 | 16 1 0 8 0 6 30 3 1 0 0 210 | 18 0 0 13 0 19 37 3 1 1 0 211 | 16 0 0 10 0 13.2 32 3 1 0 0 212 | 16 0 0 22 0 22.5 44 3 1 0 1 213 | 16 1 0 10 0 15 32 3 1 0 1 214 | 17 0 1 15 0 6.88 38 3 1 0 1 215 | 12 0 0 26 0 11.84 44 3 1 0 1 216 | 14 0 0 16 0 16.14 36 3 1 0 0 217 | 18 0 1 14 0 13.95 38 3 1 0 1 218 | 12 0 1 38 0 13.16 56 3 1 0 1 219 | 12 1 0 14 0 5.3 32 1 1 0 1 220 | 12 0 1 7 0 4.5 25 3 1 0 1 221 | 18 1 1 13 0 10 37 3 1 0 0 222 | 10 0 0 20 0 10 36 3 1 0 1 223 | 16 0 0 7 1 10 29 2 1 0 1 224 | 16 0 1 26 0 9.37 48 3 1 0 1 225 | 16 0 0 14 0 5.8 36 3 1 0 1 226 | 13 0 0 36 0 17.86 55 3 1 0 0 227 | 12 0 0 24 0 1 42 3 1 0 1 228 | 14 1 0 41 0 8.8 61 3 1 0 1 229 | 16 0 0 7 0 9 29 1 1 0 1 230 | 17 1 0 14 0 18.16 37 3 1 0 0 231 | 12 1 1 1 0 7.81 19 3 1 0 0 232 | 16 0 1 6 0 10.62 28 3 1 1 1 233 | 12 0 1 3 0 4.5 21 3 1 0 1 234 | 15 0 0 31 0 17.25 52 3 1 0 1 235 | 13 0 1 14 0 10.5 33 3 1 1 1 236 | 14 0 1 13 0 9.22 33 3 1 0 1 237 | 16 0 0 26 1 15 48 1 1 1 1 238 | 18 0 0 14 0 22.5 38 3 1 0 1 239 | 13 0 1 33 0 4.55 52 3 2 0 1 240 | 12 0 0 16 0 9 34 3 2 0 1 241 | 18 0 0 10 0 13.33 34 3 2 0 1 242 | 14 0 0 22 0 15 42 3 2 0 0 243 | 14 0 0 2 0 7.5 22 3 2 0 0 244 | 12 1 1 29 0 4.25 47 3 2 0 1 245 | 12 0 0 43 0 12.5 61 3 2 1 1 246 | 12 0 1 5 0 5.13 23 3 2 0 1 247 | 16 1 1 14 0 3.35 36 1 2 0 1 248 | 12 1 0 28 0 11.11 46 3 2 0 1 249 | 11 1 1 25 0 3.84 42 1 2 0 1 250 | 12 0 1 45 0 6.4 63 3 2 0 1 251 | 14 1 0 5 0 5.56 25 3 2 0 0 252 | 12 1 0 20 0 10 38 3 2 1 1 253 | 16 0 1 6 0 5.65 28 3 2 0 1 254 | 16 0 0 16 0 11.5 38 3 2 0 1 255 | 11 0 1 33 0 3.5 50 3 2 0 1 256 | 13 1 1 2 0 3.35 21 3 2 0 1 257 | 12 1 1 10 0 4.75 28 3 2 0 0 258 | 14 1 0 44 0 19.98 64 3 2 0 1 259 | 14 1 1 6 0 3.5 26 3 2 0 1 260 | 12 0 1 15 0 4 33 3 2 0 0 261 | 12 0 0 5 0 7 23 3 2 0 1 262 | 13 0 1 4 0 6.25 23 3 2 1 1 263 | 14 0 0 14 0 4.5 34 3 2 0 1 264 | 14 0 1 32 0 14.29 52 3 2 0 1 265 | 12 0 1 14 0 5 32 3 2 0 1 266 | 14 0 0 21 0 13.75 41 3 2 0 1 267 | 12 0 0 43 1 13.71 61 3 2 0 1 268 | 12 1 1 27 0 7.5 45 1 2 0 1 269 | 12 0 1 4 0 3.8 22 3 2 0 0 270 | 14 0 0 0 0 5 20 2 2 0 0 271 | 12 1 0 32 0 9.42 50 3 2 0 1 272 | 12 0 0 20 0 5.5 38 3 2 0 1 273 | 15 1 0 4 0 3.75 25 3 2 0 0 274 | 12 0 0 34 0 3.5 52 3 2 0 1 275 | 13 0 0 5 0 5.8 24 3 2 0 0 276 | 17 0 0 13 0 12 36 3 2 1 1 277 | 14 0 1 17 0 5 37 2 3 0 1 278 | 13 1 1 10 0 8.75 29 3 3 0 1 279 | 16 0 1 7 0 10 29 3 3 0 1 280 | 12 0 1 25 0 8.5 43 3 3 0 0 281 | 12 0 1 18 0 8.63 36 1 3 0 1 282 | 16 0 1 27 0 9 49 3 3 1 1 283 | 16 0 1 2 0 5.5 24 3 3 0 0 284 | 13 0 0 13 0 11.11 32 3 3 0 1 285 | 14 0 1 24 0 10 44 3 3 0 0 286 | 18 1 1 13 0 5.2 37 2 3 0 1 287 | 14 0 1 15 1 8 35 3 3 0 0 288 | 12 1 1 12 0 3.56 30 2 3 0 0 289 | 12 0 1 24 0 5.2 42 3 3 0 1 290 | 12 0 1 43 0 11.67 61 3 3 2 1 291 | 12 0 1 13 0 11.32 31 3 3 1 1 292 | 12 1 1 16 0 7.5 34 3 3 0 1 293 | 11 0 1 24 0 5.5 41 3 3 0 1 294 | 16 1 1 4 0 5 26 3 3 0 1 295 | 12 0 1 24 0 7.75 42 3 3 0 1 296 | 12 0 1 45 0 5.25 63 3 3 0 1 297 | 12 0 0 20 1 9 38 3 3 0 1 298 | 12 0 1 38 0 9.65 56 3 3 0 1 299 | 18 1 0 10 0 5.21 34 3 3 0 1 300 | 11 0 1 16 0 7 33 1 3 0 1 301 | 12 1 1 32 0 12.16 50 1 3 0 1 302 | 16 1 1 2 0 5.25 24 3 3 0 0 303 | 13 1 1 28 0 10.32 47 3 3 0 0 304 | 16 0 0 3 0 3.35 25 1 3 0 0 305 | 13 0 1 8 1 7.7 27 3 3 0 0 306 | 12 0 1 44 0 9.17 62 3 3 1 1 307 | 12 1 0 12 0 8.43 30 3 3 0 1 308 | 12 1 0 8 0 4 26 1 3 0 1 309 | 12 0 1 4 0 4.13 22 3 3 0 1 310 | 12 1 1 28 0 3 46 3 3 0 1 311 | 13 1 1 0 0 4.25 19 3 3 0 0 312 | 14 1 0 1 0 7.53 21 3 3 0 0 313 | 14 0 1 12 0 10.53 32 3 3 1 1 314 | 12 0 1 39 0 5 57 3 3 0 1 315 | 12 0 1 24 0 15.03 42 3 3 0 1 316 | 17 0 1 32 0 11.25 55 1 3 0 1 317 | 16 0 0 4 0 6.25 26 1 3 0 0 318 | 12 0 1 25 0 3.5 43 1 3 0 0 319 | 12 0 0 8 0 6.85 26 1 3 0 0 320 | 13 0 1 16 0 12.5 35 3 3 0 1 321 | 12 1 0 5 0 12 23 3 3 0 0 322 | 13 0 0 31 0 6 50 3 3 0 0 323 | 12 0 1 25 0 9.5 43 3 3 0 0 324 | 12 0 1 15 0 4.1 33 3 3 0 1 325 | 14 1 1 15 0 10.43 35 3 3 0 1 326 | 12 0 1 0 0 5 18 3 3 0 0 327 | 12 0 0 19 0 7.69 37 3 3 0 1 328 | 12 0 1 21 0 5.5 39 1 3 0 0 329 | 12 0 1 6 0 6.4 24 3 3 0 0 330 | 12 0 1 14 1 12.5 32 3 3 0 1 331 | 13 0 1 30 0 6.25 49 3 3 0 1 332 | 12 0 1 8 0 8 26 3 3 0 0 333 | 9 0 0 33 1 9.6 48 3 3 0 0 334 | 13 0 0 16 0 9.1 35 2 3 0 0 335 | 12 1 1 20 0 7.5 38 3 3 0 0 336 | 13 1 1 6 0 5 25 3 3 0 1 337 | 12 0 1 10 1 7 28 3 3 0 1 338 | 13 1 1 1 0 3.55 20 3 3 0 0 339 | 12 1 0 2 0 8.5 20 1 3 0 0 340 | 13 1 1 0 0 4.5 19 3 3 0 0 341 | 16 0 0 17 0 7.88 39 1 3 0 1 342 | 12 0 1 8 0 5.25 26 3 3 0 0 343 | 12 1 0 4 0 5 22 3 3 0 0 344 | 12 0 1 15 0 9.33 33 3 3 0 0 345 | 12 0 1 29 0 10.5 47 3 3 0 1 346 | 12 1 1 23 0 7.5 41 1 3 0 1 347 | 12 1 1 39 0 9.5 57 3 3 0 1 348 | 12 1 1 14 0 9.6 32 3 3 0 1 349 | 17 1 1 6 0 5.87 29 1 3 0 0 350 | 14 1 0 12 1 11.02 32 3 3 0 1 351 | 12 1 1 26 0 5 44 3 3 0 0 352 | 14 0 1 32 0 5.62 52 3 3 0 1 353 | 15 0 1 6 0 12.5 27 3 3 0 1 354 | 12 0 1 40 0 10.81 58 3 3 0 1 355 | 12 0 1 18 0 5.4 36 3 3 1 1 356 | 11 0 1 12 0 7 29 3 3 0 0 357 | 12 1 1 36 0 4.59 54 3 3 2 1 358 | 12 0 1 19 0 6 37 3 3 0 1 359 | 16 0 1 42 0 11.71 64 3 3 1 0 360 | 13 0 1 2 0 5.62 21 2 3 0 1 361 | 12 0 1 33 0 5.5 51 3 3 0 1 362 | 12 1 1 14 0 4.85 32 3 3 0 1 363 | 12 0 0 22 0 6.75 40 3 3 0 0 364 | 12 0 1 20 0 4.25 38 3 3 0 1 365 | 12 0 1 15 0 5.75 33 3 3 0 1 366 | 12 0 0 35 0 3.5 53 3 3 0 1 367 | 12 0 1 7 0 3.35 25 3 3 0 1 368 | 12 0 1 45 0 10.62 63 3 3 1 0 369 | 12 0 1 9 0 8 27 3 3 0 0 370 | 12 1 1 2 0 4.75 20 3 3 0 1 371 | 17 1 0 3 0 8.5 26 3 3 0 0 372 | 14 0 1 19 1 8.85 39 1 3 0 1 373 | 12 1 1 14 0 8 32 3 3 0 1 374 | 4 0 0 54 0 6 64 3 4 0 1 375 | 14 0 0 17 0 7.14 37 3 4 0 1 376 | 8 0 1 29 0 3.4 43 1 4 0 1 377 | 15 1 1 26 0 6 47 3 4 0 0 378 | 2 0 0 16 0 3.75 24 2 4 0 0 379 | 8 0 1 29 0 8.89 43 1 4 0 0 380 | 11 0 1 20 0 4.35 37 3 4 0 1 381 | 10 1 1 38 0 13.1 54 1 4 0 1 382 | 8 1 1 37 0 4.35 51 1 4 0 1 383 | 9 0 0 48 0 3.5 63 3 4 0 0 384 | 12 0 1 16 0 3.8 34 3 4 0 0 385 | 8 0 1 38 0 5.26 52 3 4 0 1 386 | 14 0 0 0 0 3.35 20 1 4 0 0 387 | 12 0 0 14 1 16.26 32 1 4 0 0 388 | 12 0 1 2 0 4.25 20 3 4 0 1 389 | 16 0 0 21 0 4.5 43 3 4 0 1 390 | 13 0 1 15 0 8 34 3 4 0 1 391 | 16 0 1 20 0 4 42 3 4 0 0 392 | 14 0 1 12 0 7.96 32 3 4 0 1 393 | 12 1 0 7 0 4 25 2 4 0 0 394 | 11 0 0 4 0 4.15 21 3 4 0 1 395 | 13 1 0 9 0 5.95 28 3 4 0 1 396 | 12 1 1 43 0 3.6 61 2 4 0 1 397 | 10 1 0 19 0 8.75 35 3 4 0 0 398 | 8 0 1 49 0 3.4 63 3 4 0 0 399 | 12 0 1 38 0 4.28 56 3 4 0 1 400 | 12 0 1 13 0 5.35 31 3 4 0 1 401 | 12 0 1 14 0 5 32 3 4 0 1 402 | 12 0 0 20 0 7.65 38 3 4 0 0 403 | 12 0 1 7 0 6.94 25 3 4 0 0 404 | 12 0 1 9 1 7.5 27 3 4 1 1 405 | 12 0 1 6 0 3.6 24 3 4 0 0 406 | 12 1 1 5 0 1.75 23 3 4 0 1 407 | 13 1 1 1 0 3.45 20 1 4 0 0 408 | 14 0 0 22 1 9.63 42 3 4 0 1 409 | 12 0 1 24 0 8.49 42 3 4 0 1 410 | 12 0 1 15 1 8.99 33 3 4 0 0 411 | 11 1 1 8 0 3.65 25 3 4 0 1 412 | 11 1 1 17 0 3.5 34 3 4 0 1 413 | 12 1 0 2 0 3.43 20 1 4 0 0 414 | 12 1 0 20 0 5.5 38 3 4 0 1 415 | 12 0 0 26 1 6.93 44 3 4 0 1 416 | 10 1 1 37 0 3.51 53 1 4 0 1 417 | 12 0 1 41 0 3.75 59 3 4 0 0 418 | 12 0 1 27 0 4.17 45 3 4 0 1 419 | 12 0 1 5 1 9.57 23 3 4 0 1 420 | 14 0 0 16 0 14.67 36 1 4 0 1 421 | 14 0 1 19 0 12.5 39 3 4 0 1 422 | 12 0 0 10 0 5.5 28 3 4 0 1 423 | 13 1 0 1 1 5.15 20 3 4 0 0 424 | 12 0 1 43 1 8 61 1 4 0 1 425 | 13 0 0 3 0 5.83 22 1 4 0 0 426 | 12 0 1 0 0 3.35 18 3 4 0 0 427 | 12 1 1 26 0 7 44 3 4 0 1 428 | 10 0 1 25 1 10 41 3 4 0 1 429 | 12 0 1 15 0 8 33 3 4 0 1 430 | 14 1 1 10 0 6.88 30 3 4 0 0 431 | 11 0 1 45 1 5.55 62 3 4 0 0 432 | 11 0 0 3 0 7.5 20 1 4 0 0 433 | 8 0 0 47 1 8.93 61 2 4 0 1 434 | 16 0 1 6 0 9 28 1 4 0 1 435 | 10 1 1 33 0 3.5 49 3 4 0 0 436 | 16 0 0 3 0 5.77 25 3 4 1 0 437 | 14 0 0 4 1 25 24 2 4 0 0 438 | 14 0 0 34 1 6.85 54 1 4 0 1 439 | 11 1 0 39 0 6.5 56 3 4 0 1 440 | 12 1 1 17 0 3.75 35 3 4 0 1 441 | 9 0 0 47 1 3.5 62 3 4 0 1 442 | 11 0 0 2 0 4.5 19 3 4 0 0 443 | 13 1 0 0 0 2.01 19 3 4 0 0 444 | 14 0 1 24 0 4.17 44 3 4 0 0 445 | 12 0 0 25 1 13 43 1 4 0 1 446 | 14 0 1 6 0 3.98 26 3 4 0 0 447 | 12 0 1 10 0 7.5 28 3 4 0 0 448 | 12 0 1 33 0 13.12 51 1 4 0 1 449 | 12 0 0 12 0 4 30 3 4 0 0 450 | 12 1 1 9 0 3.95 27 3 4 0 1 451 | 11 1 0 18 1 13 35 3 4 0 1 452 | 12 0 0 10 0 9 28 3 4 0 1 453 | 8 1 1 45 0 4.55 59 3 4 0 0 454 | 9 0 1 46 1 9.5 61 3 4 0 1 455 | 7 1 0 14 0 4.5 27 2 4 0 1 456 | 11 0 1 36 0 8.75 53 3 4 0 0 457 | 13 0 0 34 1 10 53 3 5 2 1 458 | 18 0 0 15 0 18 39 3 5 0 1 459 | 17 0 0 31 0 24.98 54 3 5 1 1 460 | 16 0 1 6 0 12.05 28 3 5 1 0 461 | 14 1 0 15 0 22 35 3 5 0 1 462 | 12 0 0 30 0 8.75 48 3 5 0 1 463 | 18 0 0 8 0 22.2 32 3 5 0 1 464 | 18 0 0 5 0 17.25 29 3 5 1 1 465 | 17 0 1 3 1 6 26 3 5 0 0 466 | 13 1 0 17 0 8.06 36 3 5 0 1 467 | 16 0 0 5 1 9.24 27 1 5 1 1 468 | 14 0 1 10 0 12 30 3 5 0 1 469 | 15 0 1 33 0 10.61 54 3 5 0 0 470 | 18 0 0 3 0 5.71 27 3 5 0 1 471 | 16 0 1 0 0 10 18 3 5 0 0 472 | 16 1 0 13 0 17.5 35 1 5 0 1 473 | 18 0 0 12 0 15 36 3 5 0 1 474 | 16 0 1 6 0 7.78 28 3 5 0 1 475 | 17 0 0 7 0 7.8 30 3 5 0 1 476 | 16 1 0 14 1 10 36 3 5 0 1 477 | 17 0 1 5 0 24.98 28 3 5 0 0 478 | 15 1 1 10 0 10.28 31 3 5 0 1 479 | 18 0 1 11 0 15 35 3 5 0 1 480 | 17 0 1 24 0 12 47 3 5 0 1 481 | 16 0 0 9 0 10.58 31 3 5 1 0 482 | 18 1 0 12 0 5.85 36 3 5 0 1 483 | 18 0 0 19 0 11.22 43 3 5 0 1 484 | 14 0 1 14 0 8.56 34 3 5 0 1 485 | 16 0 1 17 0 13.89 39 3 5 1 0 486 | 18 1 0 7 0 5.71 31 3 5 0 0 487 | 18 0 0 7 0 15.79 31 3 5 0 1 488 | 16 0 1 22 0 7.5 44 3 5 0 1 489 | 12 0 1 28 0 11.25 46 3 5 0 1 490 | 16 0 1 16 0 6.15 38 3 5 0 0 491 | 16 1 0 16 0 13.45 38 1 5 0 0 492 | 16 0 1 7 0 6.25 29 3 5 0 1 493 | 12 0 1 11 0 6.5 29 3 5 0 0 494 | 12 0 1 11 0 12 29 3 5 0 1 495 | 12 0 1 16 0 8.5 34 3 5 0 0 496 | 18 0 0 33 1 8 57 3 5 0 0 497 | 12 1 1 21 0 5.75 39 3 5 0 1 498 | 16 0 0 4 0 15.73 26 3 5 1 1 499 | 15 0 0 13 0 9.86 34 3 5 0 1 500 | 18 0 0 14 1 13.51 38 3 5 0 1 501 | 16 0 1 10 0 5.4 32 3 5 0 1 502 | 18 1 0 14 0 6.25 38 3 5 0 1 503 | 16 1 0 29 0 5.5 51 3 5 0 1 504 | 12 0 0 4 0 5 22 2 5 0 0 505 | 18 0 0 27 0 6.25 51 1 5 0 1 506 | 12 0 0 3 0 5.75 21 3 5 0 1 507 | 16 1 0 14 1 20.5 36 3 5 0 1 508 | 14 0 0 0 0 5 20 3 5 2 1 509 | 18 0 0 33 0 7 57 3 5 0 1 510 | 16 1 0 38 0 18 60 3 5 0 1 511 | 18 0 1 18 1 12 42 3 5 0 1 512 | 17 0 0 3 0 20.4 26 3 5 1 0 513 | 18 0 1 40 0 22.2 64 3 5 0 0 514 | 14 0 0 19 0 16.42 39 3 5 1 0 515 | 14 0 1 4 0 8.63 24 3 5 0 0 516 | 16 0 1 11 0 19.38 33 3 5 0 1 517 | 16 0 1 16 0 14 38 3 5 0 1 518 | 14 0 0 22 0 10 42 3 5 0 1 519 | 17 0 1 13 1 15.95 36 3 5 0 0 520 | 16 1 1 28 1 20 50 3 5 0 1 521 | 16 0 1 10 0 10 32 3 5 0 1 522 | 16 1 1 5 0 24.98 27 3 5 0 0 523 | 15 0 0 5 0 11.25 26 3 5 0 0 524 | 18 0 1 37 0 22.83 61 3 5 1 0 525 | 17 0 1 26 1 10.2 49 3 5 0 1 526 | 16 1 1 4 0 10 26 3 5 0 1 527 | 18 0 1 31 1 14 55 3 5 0 0 528 | 17 0 1 13 1 12.5 36 3 5 0 1 529 | 12 0 1 42 0 5.79 60 3 5 0 1 530 | 17 0 0 18 0 24.98 41 2 5 0 1 531 | 12 0 1 3 0 4.35 21 3 5 0 1 532 | 17 0 1 10 0 11.25 33 3 5 0 0 533 | 16 0 1 10 1 6.67 32 3 5 0 0 534 | 16 0 1 17 0 8 39 2 5 0 1 535 | 18 0 0 7 0 18.16 31 3 5 0 1 536 | 16 0 1 14 0 12 36 3 5 0 1 537 | 16 0 1 22 1 8.89 44 3 5 0 1 538 | 17 0 1 14 0 9.5 37 3 5 0 1 539 | 16 0 0 11 0 13.65 33 3 5 0 1 540 | 18 0 0 23 1 12 47 3 5 0 1 541 | 12 0 0 39 1 15 57 3 5 0 1 542 | 16 0 0 15 0 12.67 37 3 5 0 1 543 | 14 0 1 15 0 7.38 35 2 5 0 0 544 | 16 0 0 10 0 15.56 32 3 5 0 0 545 | 12 1 1 25 0 7.45 43 3 5 0 0 546 | 14 0 1 12 0 6.25 32 3 5 0 1 547 | 16 1 1 7 0 6.25 29 2 5 0 1 548 | 17 0 0 7 1 9.37 30 3 5 0 1 549 | 16 0 0 17 0 22.5 39 3 5 1 1 550 | 16 0 0 10 1 7.5 32 3 5 0 1 551 | 17 1 0 2 0 7 25 3 5 0 1 552 | 9 1 1 34 1 5.75 49 1 5 0 1 553 | 15 0 1 11 0 7.67 32 3 5 0 1 554 | 15 0 0 10 0 12.5 31 3 5 0 0 555 | 12 1 0 12 0 16 30 3 5 0 1 556 | 16 0 1 6 1 11.79 28 3 5 0 0 557 | 18 0 0 5 0 11.36 29 3 5 0 0 558 | 12 0 1 33 0 6.1 51 1 5 0 1 559 | 17 0 1 25 1 23.25 48 1 5 0 1 560 | 12 1 0 13 1 19.88 31 3 5 0 1 561 | 16 0 0 33 0 15.38 55 3 5 1 1 562 | 563 | Therese Stukel 564 | Dartmouth Hitchcock Medical Center 565 | One Medical Center Dr. 566 | Lebanon, NH 03756 567 | e-mail: stukel@dartmouth.edu 568 | -------------------------------------------------------------------------------- /wiener_filtering.py: -------------------------------------------------------------------------------- 1 | """ Wiener filtering a noisy Lena: this module is buggy 2 | """ 3 | 4 | import numpy as np 5 | import scipy as sp 6 | import pylab as pl 7 | from scipy import signal 8 | 9 | 10 | def local_mean(img, size=3): 11 | """ Compute a image of the local average 12 | """ 13 | structure_element = np.ones((size, size), dtype=img.dtype) 14 | l_mean = signal.correlate(img, structure_element, mode='same') 15 | l_mean /= size**2 16 | return l_mean 17 | 18 | 19 | def local_var(img, size=3): 20 | """ Compute a image of the local variance 21 | """ 22 | structure_element = np.ones((size, size), dtype=img.dtype) 23 | l_var = signal.correlate(img**2, structure_element, mode='same') 24 | l_var /= size**2 25 | l_var -= local_mean(img, size=size)**2 26 | return l_var 27 | 28 | 29 | def iterated_wiener(noisy_img, size=3): 30 | """ Wiener filter with iterative computation of the noise variance. 31 | 32 | Do not use this: this is crappy code to demo bugs! 33 | """ 34 | noisy_img = noisy_img 35 | denoised_img = local_mean(noisy_img, size=size) 36 | l_var = local_var(noisy_img, size=size) 37 | for i in range(3): 38 | res = noisy_img - denoised_img 39 | noise = (res**2).sum()/res.size 40 | noise_level = (1 - noise/l_var ) 41 | noise_level[noise_level<0] = 0 42 | denoised_img += noise_level*res 43 | return denoised_img 44 | 45 | 46 | ################################################################################ 47 | cut = (slice(128, -128), slice(128, -128)) 48 | 49 | np.random.seed(7) 50 | 51 | lena = sp.misc.lena() 52 | noisy_lena = lena + 20*np.random.randint(3, size=lena.shape) - 30 53 | 54 | pl.matshow(lena[cut], cmap=pl.cm.gray) 55 | pl.matshow(noisy_lena[cut], cmap=pl.cm.gray) 56 | 57 | denoised_lena = iterated_wiener(noisy_lena) 58 | pl.matshow(denoised_lena[cut], cmap=pl.cm.gray) 59 | 60 | pl.show() 61 | 62 | --------------------------------------------------------------------------------