早下班系列 | 比python更稱手的兵器
有人覺得這標題有點兒像王婆賣瓜?其實要說我一開始也不是很自信。畢竟看了這篇文章里寫的信誓旦旦的:《為什么你經常加班,卻干不過那些準點開溜的同事?》,再加之久仰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編程了。回到之前提到的《為什么你經常加班,卻干不過那些準點開溜的同事?》這篇文章,原文中竟然是用程序代碼中的字符串做表數據源……將數據寫到程序里感覺也太山寨了點,這樣改數據難道還得改程序不成?而且如果數據過大,導致內存裝不下怎么辦?又或者數據想跨程序使用又該怎么辦?所以咱至少寫個文本文件之類的外存文件做數據源。
接下來就是編程了,除了加了***步的讀文件操作之外,其他都跟原文一樣
- 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)
運算結果也一致
簡單嗎?照比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算法要支持大量數據,那改起來可就不是一句兩句能完事的了,再上個多線程并行計算?我感覺您可能需要的是一位有多年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:
為了不讓eclipse影響運行速度,這里干脆拿到命令行里執行(elicpse:俺不背鍋!)
再次友情提示: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格就會在右側顯示計算出來的計時數值)
1391毫秒約等于1.4秒(請注意此處有個小數點……)
看到這樣的對比結果,我覺得啥也不用說了,請大家自己用心去體會(我也就不得寸進尺地說:其實集算器好多加速方法還沒用上呢……畢竟太欺負人了不好……)