早下班系列 | 比python更称手的兵器

发布时间:2018-01-11 分类:产品文章 Tag:,

早下班系列1

有人觉得这标题有点儿像王婆卖瓜?其实要说我一开始也不是很自信。毕竟看了这篇文章里写的信誓旦旦的:《为什么你经常加班,却干不过那些准点开溜的同事?》,再加之久仰Python的鼎鼎大名,且看过的Python的教材的前言中提到许许多多强调Python的优点:语法简单、容易上手、世间最后的正义等等(对比的当然是著名的反人类C++和潜在的反人类JAVA),我也不禁怀疑了:要做得比Python还爽,需要做到什么地步?

先看看环境实现、代码编写的效率

鉴于我是一个爱折腾的码农,又自负有那么点Python的基础,借着害死猫的好奇心驱使,便打算试试手:看看这Python到底有多简便。

要搞Python,第一步当然是安装Python解释器,那么问题来了:选Python2还是Python3?虽然看起来只是版本升级,但其实却是连语法都换代(不是升级的意思,Python3不能完全兼容Python2语法)。虽然有Python牛人说“语言不是问题,重点在于思想巴拉巴拉……”,但对于瑟瑟发抖的新人们来说,我想大多还是不希望看到:因为缺个括号,就连print都出不来Hello World了……这样的闹心事吧?对比了种种网上意见,最后还是决定支持先进:选Python3。这样就算过几年再出个语法换代的Python4、Python5啥的,至少我的Python3能比别人的Python2多活个几年。

安装完解释器,再选一个写代码的编辑器。因为最近习惯用eclipse——开源、跨平台、免安装,且支持多种插件——所以我决定在eclipse上安装个pydev来实现支持python编程的功能。百度上找了一个最简便的方法:网上在线安装。结果安好之后发现找不着pydev?再百度找问题,发现竟是pydev的版本太新了。只好先卸了再对照eclipse和jdk版本找了一个恰到好处的,一边百度一边实验,一个小时总算搞定。速度很慢?要知道网上可是有人自述弄了整整一个下午。所以对这一点我还是蛮佩服自己的。

安完编程环境后,总该爽一下了吧?先print个Hello World?完美!再找之前的文章copy一下代码……嗯?第一行import pandas报错?缺少pandas的库?这么重要的科学计算常用库为啥这python安装时就不自带一下啊?还是自己安吧……

上网继续百度……发现有说安一个anaconda……但那样我之前安的python和pydev不是都白费了?且anaconda自带的编辑器spyder编写复杂工程不够强大又容易崩溃,还有有很多anaconda没有的库你自己再添加又不知有没有什么兼容之类巴拉巴拉的问题……否决。直接安装个pandas库呢?也不行,还有一大堆pandas需要的乱七八糟的其他库等着你呢(linux一族的通病)。用pip工具安装?没有外网不行,不过还好我有。但前提是得先安pip工具本身。怎么安装?源码编译……万幸!大学英语没忘光,摸着英文线索一路搞到了pip的源码文件,瑟瑟发抖的编译通过后(此处需要使用之前的python环境),再从百度上找一个用pip安装pandas库的详细教程,附带pip pandas所有必须支持库的网址,一顿pip下来后(此处需要命令行),再回eclipse中继续试验import pandas……居然还不行!!!什么情况?抱着死马当活马医的心理,打开了python的命令行工具:python shell,试试在python shell中import pandas行不行?竟然又行了!再回eclipse里继续测试,也正常了!个中原因太过玄幻,还是找一位python界的大神来解释吧……

到这一步,总算可以开始最早提到的那篇文章中的python编程了。回到之前提到的《为什么你经常加班,却干不过那些准点开溜的同事?》这篇文章,原文中竟然是用程序代码中的字符串做表数据源……将数据写到程序里感觉也太山寨了点,这样改数据难道还得改程序不成?而且如果数据过大,导致内存装不下怎么办?又或者数据想跨程序使用又该怎么办?所以咱至少写个文本文件之类的外存文件做数据源。

python-1

接下来就是编程了,除了加了第一步的读文件操作之外,其他都跟原文一样

import pandas
f = open('D:/data.txt', 'r')
try:
a = f.read( )
finally:
f.close( )
b = []
for i in a.split("\n"):
b.append(i.split(" "))

for i in range(1, len(b)):
b[i][4] = b[i][4].replace("$",' ')
b[i][4] = b[i][4].replace(",",' ')

for i in range(1, len(b)):
for j in [1, 2, 3, 4]:
b[i][j] = eval(b[i][j])

data = pandas.DataFrame(b[1:],columns=b[0])
out = data.groupby(['STYLE','BEDROOMS']).mean()

print(out)

运算结果也一致

python-2

简单吗?照比C++,那是简单得很,但如果对比集算器呢?

集算器的安装咱就不说了,非得要问?那你一定是在逗我……

先上集算器的程序:真不是欺负你,就三行代码,而且连一个循环都用不着写!实际上,如果不是最后一列字段的数据有点特殊需要处理一下,两行就可以搞定

A
1 =file("D:/data.txt").cursor@t(#1,#2:int,#3:int,#4:float,#5;," ")
2 =A2.run(int(replace(replace(#5,"$",""),",","")):PRICE)
3 =A3.groups(STYLE,BEDROOMS;avg(SQFEET):SQFEET,avg(BATHS):BATHS,avg(PRICE):PRICE)

再看看计算的结果:与python完全一致

python-3

如果你还是有些犹豫的话,那么不妨再透露一个重要的内幕:集算器的这种使用处理方法(游标),是可以支持大数据处理的,而且只要再加个选项还可以支持多线程并行计算。而上面的python算法要支持大量数据,那改起来可就不是一句两句能完事的了,再上个多线程并行计算?我感觉您可能需要的是一位有多年python编程经验的老鸟……

再看看代码运算的效率

最后,不妨加入计时代码,看看运行程序消耗的时间。

先加python的计时代码(友情提示:计时单位是秒)

import pandas
import time
start = time.clock()
f = open('D:/data2.txt', 'r')
try:
a = f.read( )
finally:
f.close( )
b = []
for i in a.split("\n"):
b.append(i.split(" "))
for i in range(1, len(b)):
b[i][4] = b[i][4].replace("$",' ')
b[i][4] = b[i][4].replace(",",' ')
for i in range(1, len(b)):
for j in [1, 2, 3, 4]:
b[i][j] = eval(b[i][j])
data = pandas.DataFrame(b[1:],columns=b[0])
out = data.groupby(['STYLE','BEDROOMS']).mean()
elapsed = (time.clock() - start)
print(elapsed)

鉴于原有数据文件太小,体验不出什么差距,不如干脆做大一些,能更有对比价值。就做个22.3M的文本文件(就是把原有数据不断复制粘贴来把文件撑大一点)

python-4

先测试Python:

为了不让eclipse影响运行速度,这里干脆拿到命令行里执行(elicpse:俺不背锅!)

python-5

再次友情提示:python这里计时使用的单位是……嗯,处理22.3M的数据30多秒……还好我一直坚持等下去,没误以为已经卡死,给他来个Ctrl+C……

然后再看看集算器,也加入计时代码(友情提示:使用@ms选项后计时单位是毫秒

A
1 =now()
2 =file("D:/data.txt").cursor@t(#1,#2:int,#3:int,#4:float,#5;," ")
3 =A2.run(int(replace(replace(#5,"$",""),",","")):PRICE)
4 =A3.groups(STYLE,BEDROOMS;avg(SQFEET):SQFEET,avg(BATHS):BATHS,avg(PRICE):PRICE)
5 =interval@ms(A1,now())

然后再看看耗时(点击A5格就会在右侧显示计算出来的计时数值)

python-6

1391毫秒约等于1.4秒(请注意此处有个小数点……)

看到这样的对比结果,我觉得啥也不用说了,请大家自己用心去体会(我也就不得寸进尺地说:其实集算器好多加速方法还没用上呢……毕竟太欺负人了不好……)