网站性能检测评分
注:本网站页面html检测工具扫描网站中存在的基本问题,仅供参考。
简单python代码
手把手 | 嫌Python太慢?并行运算Process Pools三行代码给你4倍提速! 流量视频课程
大数据文摘作品,转载要求见文末
作者 | Adam Geitgey
编译 | 元元、Lisa、Saint、Aileen
原文链接 | https://medium/@ageitgey/quick-tip-speed-up-your-python-data-processing-scripts-with-process-pools-cf275350163a
Python绝对是处理数据或者把重复任务自动化的绝佳编程语言。要抓取网页日志?或者要调整一百万张图片?总有对应的Python库让你轻松完成任务。
然而,Python的运营速度一直饱受诟病。默认状态下,Python程序使用单个CPU的单个进程。如果你的电脑是最近十年生产的,多数情况下会有4个及以上CPU核。也就是说,当你在等程序运行结束的时候,你的计算机有75%或者更多的计算资源都是空置的!
让我们来看看如何通过并行运算充分利用计算资源。多亏有Python的concurrent.futures模块,仅需3行代码就可以让一个普通程序并行运行。
一般情况下的Python运行
比如说我们有一个文件夹,里面全是图片文件,我们想给每一张图片创建缩略图。
下面的短程序中我们使用Python自带的glob 函数获取一个包含文件夹中所有图片文件的列表,并用Pillow图片处理库获取每张图片的128像素缩略图。
这个程序遵循很常见的数据处理模式:
1. 从您想处理的一系列文件(或其他数据)开始
2. 编写一个处理一个数据的辅助函数
3. 用for循环调动辅助函数,一个一个的去处理数据
让我们用1000张图片来测试这个程序,看看运行时间是多少。
程序运行时间8.9秒,但是计算机的运算资源占用了多少呢?
让我们再跑一次程序,同时查看活动监视器:
计算机有75%空置,这是为什么呢?
问题在于我的计算机有4个CPU核,但是Python只用了其中一个核。即便我的程序把那个CPU核完全占满,但是其他3个CPU核什么也没干。我们需要想办法把整个程序的工作量分成4份然后平行运行。所幸Python可以做到这一点!
让我们来试试并行运算
下面是实现并行运算的一个方法:
1.把Jpeg图片文件列表分成4个部分。
2. 同时跑四个Python解释器。
3. 让四个解释器分别处理一部分图片文件。
4. 汇总四个解释器的结果得到最终结果。
四个Python程序分别在4个CPU上运行,跟之前在1个CPU运行相比大概可以达到4倍的速度,对不对?
好消息是Python可以帮我们解决并行运算麻烦的部分。我们仅需要告诉 Python我们想要运行什么函数以及我们希望工作分成多少份,其他部分留给Python。我们只需要修改三行代码。
首先,我们需要导入concurrent.futures库。这个库是Python自带的:
然后,我们需要告诉 Python另外启动4个Python实例。我们通过创建Process Pool来传达指令:
默认设置下,上面的代码会给计算机的每一个CPU创建一个Python进程,所以如果您的计算机有4个CPU,就会开启4个Python进程。
最后一步是让Process Pool 用这4个进程在数据列表中执行我们的辅助函数。我们可以把我们之前的for循环替代为:
新代码是调用executor.map()函数
executor.map() 函数调用时需要输入辅助函数和待处理的数据列表。这个函数帮我们完成所有麻烦的工作,把列表分成几个小列表,把小列表分配给每个子进程,运行子进程,以及汇总结果。干得漂亮!
我们也可以得到每次调用辅助函数的结果。executor.map()函数以输入数据顺序返回结果。 Python的zip()函数可以一步获取原始文件名以及相应结果。
下面是经过三步改动之后的程序:
让我们试着运行一下,看看有没有缩短运行时间:
2.274秒程序就运行完了!这便是原来版本的4倍加速。运行时间缩短的原因正是我们这次用4个CPU代替了1个CPU。
但是如果您仔细看看,您会看到“用户(User)”时间大概是接近9秒,如果程序2秒就运行结束了,为什么客户时间会是9秒?这似乎…有哪里不对?
其实这是因为”用户”时间是所有CPU时间的总和。我们和上次一样,用9秒的总CPU
注意:启用Python进程以及给子进程分配数据都会占用时间,因此您不一定能靠这个方法大幅提高速度。如果您处理的数据量很大,这里有一篇“设置chunksize参数的技巧”文章可能可以帮助您:https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.Executor.map。
这种方法总能帮我的程序提速吗?
当你有一列数据,并且每个数据都可以独立处理的时候,使用Process Pools是一个好方法。这有一些适合使用并行处理的例子:
从一系列单独的网页服务器日志里抓取数据。
从一堆XML,CSV和JSON文件中解析数据。
对大量图片数据做预处理,建立机器学习数据集。
但Process Pools不是万能的。使用Process Pool需要在独立的Python处理过程中将数据来回传递。如果你正在使用的数据不能在处理过程中有效的被传递,这种方法就行不通。你处理的数据必须是Python知道怎么搞定的类型(https://docs.python.org/3/library/pickle.html#what-can-be-pickled-and-unpickled)。
同时,数据不会按照一个预想的顺序被处理。如果你需要前一步的处理结果来进行下一步骤,这种方法也行不通。
那GIL怎么办?
你可能听说过Python有一个全局解释器锁(Global Interpreter Lock,),缩写为GIL。这意味着即使你的程序是多层的,每一层也只有一个Python命令能被执行。GIL确保任何时候都只有一个Python线程执行。 GIL最大的问题就是Python的多线程程序并不能利用多核CPU的优势。
但Process Pools能解决这个问题!因为我们在运行单独的Python实例,每个实例都有自己的GIL。这样你就有了真正的并行处理的Python代码!
不要害怕并行处理!
有了concurrent.futures库,Python可以让你简简单单地修改脚本,却能立刻调用你电脑上所有CPU内核开足马力地运行。不要害怕尝试。一旦你会用了,它就像写一个for循环那样简单,但会让整个程序快很多。
怎么样都要学几个python的简单小程序 小程序视频课程
虹之菌BUG之前在学Python的时候,参考书上或网上的代码写了几个小程序,发出来算个学习笔记,也请朋友们帮着给找找代码中错误和不严谨的地方。
一、一个简单的下载程序
用过Curl后觉得它的下载功能很帅,命令行下的,就想用Python也来写一个命令行下的下载程序。
其实用Python实现下载文件的功能很简单,用urllib模块中的urlretrieve()函数就可以了。
url是要下载文件的URL地址,frlename是文件下载后保存时的文件名,reporthook是显示下载进度的,data还不知道是干什么的。除了url参数外,另外3个参数好像都可以省略。
把代码保存为文件filedown.py。程序需要 输入两个参数,一个是要下载文件的URL地址,一个是文件下载后保存时的文件名。来下载个文件测试下程序的功能。要下载的文件我挑了个比较小的——小Q书桌的安装文件(用的移动CMCC的网络,现在是周五晚上,网速很慢,只能挑个小文件来做测试了)下载后的保存文件名QDeskSetup_25_1277.exe。打开命令提示符,切换到文件filedown.py所在的目录,输入如下命令:
回车后就开始下载文件了,下载过程中程序会动态显示已经下载的文件的大小和已经完成的百分比。
来到文件filedown.py所在的目录C:\pycode2\下,发现文件QDeskSetup_25_1277.exe已经下载好了,双击运行,程序一切正常,说明程序可以完成下载文件的功能。但那个完成进度的100.08%不知道是怎么算出来的,太刺眼,要改。另外,程序好像还缺了一个常见下载程序都有的功能一一显示实时下载速度。
把代码保存为文件filedown ver4.py。这次程序加入了显示下载速度的功能,还增加了可以手工中断正在下载的文件的功能。还是来测试下程序的功能。
回车后程序显示能显示下载速度了。
不过原来的问题解决了,新的问题又来了。
同样的机子,下载同样的文件,修改后的程序用了75.140秒,而原来的程序只用了10.969秒,说明修改后的程序下载文件的速度严重变慢了。什么原因造成的呢?我一时没找到答案,考虑过是不是加入的显示文件下载速度和下载百分比的代码执行是不是比较占用CPU,下载的时候特意看了一下任务管理器中CPU的情况,结果发现CPU使用率不高,看来不是这个原因。知道怎么回事的朋友欢迎指教。
二、计算文件的SHA1值
从网上下载了几个号称MSDN原版的Windows操作系统的安装镜像,想在虚拟机里安装几个原版系统玩玩。但下载后还有点不放心,担心文件有被修改过。于是就想验证下下载的镜像文件的哈希值。MSDN官方网站上已经给出了镜像文件的SHA1值,比如我下载的网站上给出的文件的SHA1值为2CEOB2DB34D76ED3F697CE148CB7594432405E23。如果下载的文件的SHA1值也是2CEOB2DB34D76ED3F697CE148CB7594432405E23,说明文件没被修改,可以放心使用。
计算文件的SHA1值有很多工具,但手头有Python,能少用一个第三方软件就少用一个,就考虑用Python写个计算文件SHA1值的小程序。
先上网上搜索了下相关代码,网上已经有了。网上的代码用的是hashlib模块中的shal()函数来计算SHA1值。为了处理大文件,所以需要使用shal()函数的update()方法。
一个快速将python2代码批量转为python3代码的好方法 流量视频课程
由于python存在python2和python3两个主要的版本方向,经常会有将python2的代码转到python3的环境下运行的需求。尤其是跑一些神经网络的代码时有很多是在python2的环境下写的。在python3下运行会遇见很多不兼容,最常见的就是python3中print函数必须加()而python2中不是。一个一个修改这种错误又非常麻烦。
此时一种方式是再安装一个python2,比如下载anaconda对应的python2的版本,管理相关的库,运行的时候指定python2运行。不过如果是运行依赖比较多的代码可能需要在python2的环境安装许多包。
这里介绍一个python3自带的脚本2to3.py,可以将python2的程序自动转为python3的形式,节省了很多修改细节的时间。这个脚本在Python安装目录下Toolsscripts文件夹下,如果是利用anaconda3安装的python3,就在anaconda3/Tools/scripts中,如下图:
这个文件实际是可以复制到电脑任何位置使用的,当然也可以就在这个位置利用cmd使用,里面的代码也很简单,只有几行:
使用方法也很简单,如果我需要转换某个python文件,比如E盘根目录下的test.py,只需要在命令行里输入
python 2to3.py -w E:/test.py
如果需要转换某个文件夹下的所有文件,例如E盘test文件夹下的所有文件,只需要在命令行里输入
python 2to3.py -w E:/test/
就是这么简单就可以完成python2代码像python3代码的变换,当然目前对于一些比较复杂的依赖这种方法还不能完全转换,还需要根据运行错误调整,不过已经可以节省很多的时间啦。
python实现简单的用户注册程序(含源代码) 互联网视频课程
1.系统实现要求
1.实现用户手机注册,且对手机号码输入进行校对2. 实现用户密码输入且校对。控制在8位密码。3. 实现用户重复密码输入校验。4. 将用户成功注册的账号和密码存储到文本中。待下次登陆账号使用。
模仿的客户端注册程序
2.系统源代码
# coding=utf-8mobile_str = raw_input("请输入您要注册的手机号码")try: mobile_num = int(mobile_str)except ValueError: print '您好,你输入的手机有非数字字符,请重新输入'else: if (len(mobile_str) != 11): print '您的手机号码位数不正确' else: print '您的手机正确,正在获取验证码' password_str_0 = raw_input("请输入您的密码") try: password_num_0 = int(password_str_0) except ValueError: print '您好,你输入的密码不是纯数字,请重新输入' else: if (len(password_str_0) != 8): print '您的密码位数不正确' else: password_str_1 = raw_input("请再次输入您的密码") try: password_num_1 = int(password_str_1) except ValueError: print '您好,你输入的密码不是纯数字,请重新输入' else: if (password_num_0 != password_num_1): print '您好,你输入的密码与前一次不同,请重新输入' else: print '您已成功注册' fo = open("foo.txt", "wb") fo.write('用户账号:' + mobile_str + ' ' + '用户密码:' + password_str_0);
3.系统运行结果输出
运行结果截图