带大家读python数据分析一书(三)

写在开头

  今天写博客的时候才发现CSDN里面的博客模板改版了更新了一些,好像更亲和html多一些了?连换行都要用上br了,不过无所谓这不是重点,对于我开说只要写博客不是很受影响就好了。

  吸取上次写博客写道几乎吐血的教训,这一次我会尽量的提出一些重点的东西出来。

  这一次带大家读的是第三章,然后。。。好吧,~~这第三章完全没法评价了,或者说这本书我确实无法理解作者这样,~~我就不吐槽了,套用作者原话。

注意: 在第一次阅读时,本章的许多内容都可跳过不看,因为它们对理解本书其余的内容没有影响。本章的目的是让你对IPython所提供的功能有一个全面的了解。

IPython:一种交互式计算和开发环境

  不管该不该装逼的时候这位作者老司机也没有一点儿犹豫,开篇就是

  "人们经常问我,“你的Python开发环境是什么?”我的回答基本永远都是“IPython外加一个文本编辑器”。"

  搞得我也很想这么装逼的回答,虽然到目前为止我确实一直在用Python解释器+notepad++/vim在敲python的代码,不过这位老哥水平很棒确实是真的。

  不过IPython项目现在已经不再只是一个加强版的交互式Python shell,它还有一个可以直接进行绘图操作的GUI控制台、一个基于Web的交互式笔记本,以及一个轻量级的快速并行计算引擎。

IPython基础

  IPython的启动和python shell一样都可以在命令行中敲入ipython即可打开,当然这个是在已经设置了环境的情况之下,若是当了这里读者还是不知道如何设置环境的话,希望能够自行百度或者Google了。

Tab键自动完成

  Tab键如果你是一个和博主一样很喜欢使用命令行或者Linux的人或者使用数学软件的人的话,应该不会非常的陌生。

  在命令行中如果我要进行一个文件夹的话我必须输入指令“cd 文件夹名”,文件夹名如果较短的话还可以接受,但是如果文件夹名字比较长的话就很难受了,这个时候这里就有一个辅助功能了,输入文件夹的前一两个文字然后按它就会自动补全了,可以说是一个非常实惠的功能。

  同样这里的IPython也有这样子的功能,这也是它优于python shell的一点,比如我有个变量名叫thenumbermovefromthe_folder1,这个时候只要你键入the再按就能够自动补全了。

  IPython的补全功能不仅能够补全变量名,对于函数名也有提示和补全的功能。

内省

  啥叫内省,在这本书第一次看到这个名字的时候博主是一脸懵逼的,看过才直到用了这么久的东西总算是有个称呼了。

  在变量的前面或后面加上一个问号(?)就可以将有关该对象的一些通用信息显示出来,这就叫做对象内省(object introspection)。如果该对象是一个函数或实例方法,则其docstring(如果有的话)也会被显示出来。

  看完这个你可能还是一脸懵逼的,简单来说这个东西就是一个类似于help的东西,你在接触一个新东西,不知道它有啥性质的时候,你就可以打个问号给它,然后IPython就会给出它的解释(前提是有)。

  这个?还有一个功能就是搜索IPython的命名空间,是啥呢?是一个通用匹配字符,如果学过正则表达式的话就能够很好的理解,可以替换任意的一个字符。

%run命令

  %run的用法是 %run + 文件名.py 就是在IPython中运行py文件,一个强大之处就是运行之后文件中的变量就可以在ipython中使用了(此时要使用%run - 1 来运行代码文件)。

  Ctrl + C , 我觉得这算是一个程序员用的最多的快捷键了,不仅仅只是copy的功能,在程序运行之中还有中断运行程序的作用,在你运行程序的时候你发现之前的程序出现了问题,这个时候你就可以使用这个命令强行终止这个程序的运行。

警告: 当Python代码已经调用了某个已编译的扩展模块时,按下“Ctrl-C”将无法使程序立即停止执行。在这种情况下,要么只能等待Python解释器重新获得控制权,要么只能通过操作系统的任务管理器强制终止Python进程(比较极端的情况下才需要这么干)。

执行剪贴板的代码

  我们有的时候在网上参考(copy)了人家的代码之后,我们想直接粘贴执行,这个时候要怎么做呢?

  我们都可以通过“Ctrl-Shift-V”(windows下用鼠标右键点击粘贴)。注意,这并不是万试万灵的,因为这种粘贴方式模拟的是在IPython中逐行输入代码,换行符会被处理为。也就是说,如果你所粘贴的是一段缩进代码,且其中有一个空行,IPython就会认为缩进在空行那里结束了。当执行到缩进块后面那行代码时,就会引发一个IndentationError。

  这个时候我们应该使用%paste和%cpaste这两个魔术函数。%paste可以承载剪贴板中的一切文本,并在shell中以整体形式执行,具体就是我在粘贴代码之前加一句%paste就好了(%cpaste跟%paste差不多,只不过它多出了一个用于粘贴代码的特殊提示符而已).

警告: 根据你的系统平台以及Python的安装情况,%paste可能会不起作用。EPDFree(在第1章中介绍过)等打包发布的版本应该没有问题。

键盘快捷键

  看了一下这里介绍的指令可能用的不是很多(如果你不是在linux下开发的话)

异常与跟踪

  在IPython中如果你的代码有错误的话,它确实会提示你代码错误的地方,并且在那里标注出它的错误,你也可以使用%xmode来控制上下文代码参考的数量。

魔术命令

  一直觉得魔术命令挺牛逼的,但是一直没有什么机会可以使用(python shell是没有的),不过还是有所了解的,这种指令非常的简答都是一个%+指令,但是功能却非常的强大。以下是常用的IPython魔术命令:

基于Qt的富GUI控制台

  IPython团队开发了一个基于Qt框架(其目的是为终端应用程序提供诸如内嵌图片、多行编辑、语法高亮之类的富文本编辑功能)的GUI控制台。如果你已经安装了PyQt或PySide,使用下面这条命令来启动的话即可为其添加绘图功能:

  ipython qtconsole --pylab=inline

  Qt控制台可以通过标签页的形式启动多个IPython进程,这就使你能够在多个任务之间轻松切换。它也可以跟IPython HTML Notebook应用程序共享同一个进程,博主虽然对这些不是非常的熟悉,但是这之后我尽量的将其讲解的清楚一些。

matplotlib集成与pylab模式

  导致IPython广泛应用于科学计算领域的部分原因是它能跟matplotlib这样的库以及其他GUI工具集默契配合。这功能就有点牛皮了(对于一个常年使用Python shell的人来说),具体是啥意思呢,在python shell的时候你画图你会发现,当它画出图来了,你发先你无法进行命令行的控制了,你必须关闭图画才可以继续,而这个就厉害了,一边显示图片一边跑代码。命令是:

  $ ipython --pylab

  这样会导致几个结果

第一,IPython会启用默认GUI后台集成,这样matplotlib绘图窗口的创建就没问题了。

第二,NumPy和matplotlib的大部分功能会被引入到最顶层的interactive命名空间以产生一个交互式的计算环境(就像MATLAB和其他领域特定型科学计算环境那样)。也可以通过%gui对此进行手工设置(详情请执行%gui?)。

使用命令历史

  IPython维护着一个位于硬盘上的小型数据库,其中含有你执行过的每条命令的文本。这样做有几个目的:

只需很少的按键次数即可搜索、自动完成并执行之前已经执行过的命令。

在会话间持久化命令历史。

将输入/输出历史记录到日志文件。

搜索并重用命令历史

  为什么会需要这个功能呢?其实很容易理解,毕竟没有人能够一次就能把所有的东西都做好,总是有一个反复尝试的过程,当你输入指令之后你发现自己整错了,这个时候你可以修改好之后直接输入指令的签几个字符然后按“Ctrl-P”键或上箭头键即可。(python shell种直接按箭头上即可)

输入和输出变量

   不知道有没有大家试过运行一段很复杂的函数之后,运行很长时间之后,自己才发现运行的结果忘记赋值了(保存下来),这个IPython有一个很好的机制就是最近的两个输出结果会保存在—(一个下划线)——(两个下划线)中,不过也会遇到一些小问题,可以看看警告:

警告: 在处理非常大的数据集时,一定要注意IPython的输入输出历史,它会导致所有对象引用都无法被垃圾收集器处理(即释放内存),即使用del关键字将变量从interactive命名空间中删除也不行。对于这种情况,谨慎地使用%xdel和%reset将有助于避免出现内存方面的问题。

记录输入和输出

  在IPython中能够记录整个控制台会话,包括输入和输出。执行%logstart即可开始记录日志,IPython的日志功能可以在任何时刻开启,它将记录你的整个会话(包括此前的命令)。因此,如果你在写代码的过程中,突然想要保存所有工作的时候,直接启动日志功能就行了。%logstart的具体选项(比如修改输出文件路径)请参考其文档,此外还可以看看几个与之配套的魔术命令%logoff、%logon、%logstate以及%logstop。

与操作系统交互

  IPython的另一个重要特点就是它跟操作系统shell结合得非常紧密。意思就是在命令行中使用的指令也可以在IPython之中使用。以下是跟系统相关的IPython魔术命令:

shell命令和别名

  在IPython中,以感叹号(!)开头的命令行表示其后的所有内容需要在系统shell中执行。这意味着,就算你用的是IPython,但是你仍然有办法可以通过指令直接的操作shell的内容,还是蛮好用的。

目录书签系统

  这个书签系统我也是第一次见,挺神奇的,不过很简单,估计学会的人都会忍不住的迷上吧。

  具体是命令形式是如下这样子的

%bookmark 自定义名字 实际目录路径-l 可以查看当前已有的书签-b可以覆盖已有的书签名

软件开发工具

  IPython不仅是一种舒适的交互式计算和数据分析环境,同时也非常适合成为一种软件开发环境。在数据分析应用程序中,最重要的事情就是拥有正确的代码。幸运的是,IPython紧密集成并加强了Python内置的pdb调试器。此外,你还希望代码运行能足够快。为此,IPython提供了一些简单易用的代码运行时间及性能分析工具。下面,我将对这些工具做一个详细介绍。

交互式调试器

  毫无疑问,IPython是增强了pdb的,比如上文说到的Tab自动补全、错误信息回馈,还有一下就会接触到的语法高亮等等。

  这本书这里具体给大家介绍了一下代码调试错误的过程。

  简单讲一下吧,%debug使用这个指令当你运行之后发现报错了会直接跳转到引发异常的那个栈帧(stack frame),

  执行%pdb命令可以让IPython在出现异常之后自动调用调试器。此外,调试器还可以为代码开发工作提供帮助,尤其是当你想要设置断点或对函数/脚本进行单步调试以查看各条语句的执行情况时。实现这个目的的方式有几个。

使用带有-d选项的%run命令,这将会在执行脚本文件中的代码之前先打开调试器。必须立即输入s(或step)才能进入脚本:

输入c(或continue)使脚本一直运行下去直到该断点时为止:

这时可以单步进入worksfine()或执行worksfine()(输入n(或next)直接执行到下一行)

在变量前面加上感叹号(!)即可查看内容(那个范围之类的变量)。

  一下是一些常见的指令

调试器的其他使用场景

  除上面提到的之外,还有另外几种调用调试器的手段。最常用的就是两种吧。

  第一个函数是set_trace,这个非常简单。你可以将其放在代码中任何希望停下来查看一番的地方(比如发生异常的地方),或者之前运行出错过的地方,然后按下c(或continue)仍然会使代码恢复执行,不受任何影响。

  第二个就是debug函数使你能够直接在任意函数上使用调试器。怎么使用呢?其实很简单,把函数当作一个参数传入就可以了,然后这个函数输入什么参数,直接输入个debug函数即可。

测试代码的执行时间:%time和%timeit

  说到这两个魔术指令,如果需要测试时间的时候确实是非常的实用了,对比于一个魔术指令就能够测试出时间的方式无疑是比shell中要方便很多,简单介绍一下使用方法

  %time 直接%time + 运行指令 ,然后就会出现运行时间了

  %timeit 然后这个看上去很相似的函数有什么作用呢?实际上就是把指令自动运行多次取平均的时间(要是这个指令运行一次要很久岂不是哭死?)

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

  主要的Python性能分析工具是cProfile模块,这个不是专门为IPython使用的,所以在shell中也能够使用,一般是怎么用的?

python -m cProfile -s 排序方式 文件名

  即可使用,然后%prun 和%run -p 是和上述有一样功能的魔术指令(这个魔术指令分析的是一个语句而不是上述的文件)。

%prun -m cProfile -s 排序方式 语句%run -p -m cProfile -s 排序方式 语句

逐行分析函数性能

  有些时候,从%prun(或其他基于cProfile的性能分析手段)得到的信息要么不足以说明函数的执行时间,要么就复杂到难以理解(按函数名聚合)。对于这种情况,我们可以使用一个叫做lineprofiler的小型库(可以通过PyPI或随便一种包管理工具获取)。其中有一个新的魔术函数%lprun,它可以对一个或多个函数进行逐行性能分析。你可以修改IPython配置(参考IPython文件或本章稍后关于配置的内容)以启用这个扩展.

  这个新的魔术指令%lprun是怎么用的呢?用法上唯一的区别就是:必须为%lprun指明想要测试哪个或哪些函数。%lprun的通用语法为:

%lprun -f func1 -f func2 statementtoprofile

  这两者的却别主要是什么呢?%lprun主要能够一条语句、一行一行的给的罗列出详细的信息,而之前那个是总体的大概信息。

通常用%prun(cProfile)做“宏观的”性能分析,而用%lprun(lineprofiler)做“微观的” 性能分析。这两个工具都很有必要了解一下。

注意: 在使用%lprun时,之所以必须显式指明待测试的函数名,是因为“跟踪”每一行代码的执行时间所需的开销很大。对不感兴趣的函数进行跟踪将会对性能分析结果造成显著的影响。

IPython HTML Notebook

  说实话刚刚看到这个名字的时候还没有反应过来,等细看了内容介绍的时候,发现是一个和jupyter notebook相似的东西,但是具体性能差别如何博主本人倒是没有比较直观的体验。  运行的时候只需要输入

  ipython notebook --pylab-inline

  就可以运行了,你默认的浏览器会自动打开的。

利用IPython提高代码开发效率的几点提示

  为了在IPython中开发、调试代码,并充分发挥其交互优势,许多用户都需要转换一下工作模式。像编码风格以及一些操作细节可能需要做一些调整。

  就这点来说,本节的内容更像是艺术而非科学,你需要有一些编程经验才好判断其能否提高你的工作效率。总之,你得让你的代码结构更易于交互且结果更易于查看。我发现通过IPython设计的软件要比独立的命令行应用程序好用。当你执行自己或别人在几个月甚至几年前编写的代码时出现了错误,想找出问题所在时,IPython的交互性就会变得非常重要。

重新加载模块依赖项

  这里要提示的是什么呢?

  在python对库进行导入的时候,它是一次性载入的somelib中的代码就会被执行,且其中所有的变量、函数和引入项都会被保存在一个新建的somelib模块命名空间中。下次你再输入import some_lib时,就会得到这个模块命名空间的一个引用,这意味着就算你刚刚修改了模块,但是在后面再次import的时候还是没有修改的时候。

  这个时候怎么办呢?只需要在import之后加一句

reload(some_lib)

  即可

代码设计提示保留有意义的对象和数据

  看了一下子吧,这个地方讲的不是非常的明白,但是比如main这样子的名字就尽量的避免使用是最好了。

扁平结构要比嵌套结构好

  深度嵌套的代码让我想到了洋葱。在测试或调试函数时,你要把这个洋葱剥多少层才能找到感兴趣的代码?“扁平结构要比嵌套结构好”的思想来自“Zen of Python”,它对交互式的代码开发模式同样有效。编写函数和类时应尽量注意低耦合和模块化,这样可以使它们更易于测试(如果你编写单元测试的话)、调试和交互式使用。

无惧大文件

  这算是什么原则呢?在一些其他的语言中,比如java中就会尽量的避免大文件的出现,尽量保持小文件,但是如果你真保持这个情况的话,那面对非常多的文件的时候你是会非常头疼的,可以适当地安排一些比较大的文件,当然也不是极端化的全部放在一个文件里面,这样子日后的维护会显得非常的艰难。

高级IPython功能让你的类对IPython更加友好

  IPython力求为各种对象呈现一个友好的字符串表示。对于许多对象(如字典、列表和元组等),内置的pprint模块就能给出漂亮的格式。但是对于你自己定义的那些类,就必须自己生成所需的字符串输出。假设我们有下面这个简单的类:

如果像下面这样写,你就会失望地发现这个类的默认输出形式非常不好看:

由于IPython会获取repr方法返回的字符串(具体办法是output = repr(obj)),并将其显示到控制台上。因此,我们可以为上面那个类添加一个简单的repr方法以得到一个更有意义的输出形式:

个性化和配置

  IPython shell在外观(如颜色、提示符、行间距等)和行为方面的大部分内容都是可以进行配置的。下面是能够通过配置做的部分事情:

修改颜色方案。

修改输入输出提示符。

去掉Out提示符跟下一个In提示符之间的空行。

执行任意Python语句。这些语句可以用于引入所有常用的东西,还可以做一些你希望每次启动IPython都发生的事情。

启用IPython扩展,如line_profiler中的魔术命令%lprun。

定义你自己的魔术命令或系统别名。

所有这些配置选项都定义在一个叫做ipythonconfig.py的文件中,可以在~/.config/ipython/目录(UNIX)和%HOME%/.ipython/ 目录(Windows)中找到。具体的主目录取决于你的系统。配置信息是基于特定个性化设置的。一般来说,正常启动IPython将会加载默认的个性化设置(位于profiledefault目录中)。因此,在我的Linux系统中,默认IPython配置文件的完整路径是:

/home/wesm/.config/ipython/profiledefault/ipythonconfig.py

这里我就不对该文件的内容作详细介绍了。因为其注释已经说明了各个配置项的功能,各位读者完全可以自己照着做。还有一个很实用的功能是拥有多个个性化设置。假设你想要专门为某个应用程序或项目量身定做一套IPython配置。输入下面这样的命令即可新建一个个性化设置:

ipython profile create secret_project

然后编辑新建的这个profilesecretproject目录中的配置文件,再用下面这种方式启动>

IPython:$ ipython --profile=secretprojectPython 2.7.2 |EPD 7.1-2 (64-bit)| (default, Jul 3 2011, 15:17:51)Type "copyright", "credits" or "license" for more information.IPython 0.13 -- An enhanced Interactive Python.? -> Introduction and overview of IPython's features.%quickref -> Quick reference.help -> Python's own help system.object? -> Details about 'object', use 'object??' for extra details.IPython profile: secretprojectIn [1]:

同样,有关个性化和配置方面的详细信息,请参考IPython的在线文档。

致谢

  本章的部分内容由IPython Development Team整理。我对他们创建了如此神奇的工具而感激涕零。

  感觉没啥好说呢。。。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180922G0MJLD00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券