早下班系列:比python更稱(chēng)手的兵器-續(xù)
話(huà)說(shuō)上一回(早下班系列:比python更稱(chēng)手的兵器),本菜鳥(niǎo)剛揶揄了一番某python培訓(xùn)班的代碼,結(jié)果還沒(méi)等收到其他小伙伴的紛紛好評(píng),就先被本公司的大俠給打臉了。
大俠給出了如下代碼:
- import pandas as pd
- data = pd.read_table(‘D:/data.txt’,sep=‘ ‘)
- data.PRICE = data.PRICE.str[1:].str.replace(‘,’,”).astype(‘int64’)
- out = data.groupby([‘STYLE’,‘BEDROOMS’]).mean()
刨除import語(yǔ)句后,同樣是三行代碼!而運(yùn)行效率嘛,也跟集算器也差不多:同樣是1.4s左右!
這可真是:出師未捷臉被打,常使菜鳥(niǎo)淚……不對(duì),菜鳥(niǎo)還不能就此放棄……
仔細(xì)一想,如果連對(duì)付這么簡(jiǎn)單的一個(gè)22.3M的小量數(shù)據(jù)都做得那么水,那鼎鼎大名的python在編程語(yǔ)言界也就不用混了,谷歌、臉書(shū)等那么賣(mài)力推薦python更只會(huì)被視為腦殘。
那么上一篇文章真正得出的結(jié)論其實(shí)是:就算你參加了好幾個(gè)月的python培訓(xùn)班,畢業(yè)之后,你的python可能也只能寫(xiě)出類(lèi)似上一篇的那種被我這樣的菜鳥(niǎo)還瘋狂嘲諷的代碼。
所以,今天的再次對(duì)比,咱就不玩上次的那種“菜雞互啄”式的對(duì)比了,上點(diǎn)干貨:
一、玩一點(diǎn)真正的大數(shù)據(jù)計(jì)算
上次偷了個(gè)懶,弄個(gè)22.3M的東西來(lái)冒充大數(shù)據(jù),結(jié)果慘遭打臉,至今仍隱隱作疼……這次不敢再偷懶了,既然說(shuō)是大數(shù)據(jù),那不上他個(gè)幾G的,也敢稱(chēng)為“大”么?
這回咱先上集算器的:
A | |
1 | =file(“D:/data.txt”).cursor@t(#1,#2:decimal,#3:int,#4:decimal,#5;,” “) |
2 | =A1.run(decimal(replace(replace(#5,”$”,””),”,”,””)):PRICE) |
3 | =A2.groups(STYLE,BEDROOMS;avg(SQFEET):SQFEET,avg(BATHS):BATHS,avg(PRICE):PRICE) |
相比上次代碼基本沒(méi)變動(dòng)多少,就是幾個(gè)涉及要計(jì)算平均值的數(shù)據(jù)類(lèi)型,從int改成了decimal。畢竟是用大數(shù)據(jù)去計(jì)算聚合函數(shù)嘛,若還用int那就等著被爆出負(fù)數(shù)吧……
至于計(jì)算結(jié)果,看一看SQFEET、BATHS和PRICE三列就知道:因?yàn)槭怯?jì)算平均值,而大數(shù)據(jù)文件其實(shí)是用整塊原始數(shù)據(jù)循環(huán)復(fù)制粘貼出來(lái)的,所以最終結(jié)果,跟原先一模一樣,所以是完全正確地!
然后該python了,同樣先上代碼
- import pandas as pd
- data = pd.read_table(‘D:/data.txt’,sep=‘ ‘)
- data.PRICE = data.PRICE.str[1:].str.replace(‘,’,”).astype(‘int64’)
- print(data.groupby([‘STYLE’,‘BEDROOMS’]).mean())
接下來(lái)該測(cè)試結(jié)果了……咳,不出所料,python家的pandas愉快地罷工了(內(nèi)存溢出)
二、讀個(gè)其他類(lèi)型的文件試試
上次弄的TXT文本文件,是不是覺(jué)得看著太Low,不上檔次?這回咱就讀個(gè)Excel吧。
鑒于python要處理大數(shù)據(jù)文件實(shí)在有點(diǎn)麻煩(且本人也比較懶),就不拿大數(shù)據(jù)繼續(xù)欺負(fù)python了。回到一開(kāi)始的小數(shù)據(jù)文件進(jìn)行測(cè)試。只不過(guò)咱給他改成Excel的。
同樣先上集算器的:變兩行代碼了(得感謝Excel的金額類(lèi)數(shù)值的固定格式)
A | |
1 | =file(“D:/data.xlsx”).importxls@tc() |
2 | =A1.groups(STYLE,BEDROOMS;avg(SQFEET):SQFEET,avg(BATHS):BATHS,avg(PRICE):PRICE) |
計(jì)算結(jié)果依舊:
接下來(lái)該上python了,主要代碼倒也是兩行
- import pandas as pd
- data = pd.read_excel(‘D:/data.xlsx’,sheet_name=0)
- print(data.groupby([‘STYLE’,‘BEDROOMS’]).mean())
計(jì)算結(jié)果也完全一樣
不過(guò)計(jì)算前別忘了安裝xlrd和xlwt兩個(gè)庫(kù),否則pandas會(huì)報(bào)錯(cuò)給你看哦!至于怎么安裝這兩個(gè)庫(kù)?不難,反正我是用pip在線(xiàn)安裝的。怎么安裝pip?呵呵,請(qǐng)看本系列的***篇
這個(gè)比較,就算打個(gè)平手吧,畢竟python也不是吃素的。
三、算一點(diǎn)稍微復(fù)雜的東西
如果覺(jué)得平時(shí)你不需要處理多大的數(shù)據(jù),也不嫌安python的各種第三方庫(kù)麻煩(反正主要就折騰一次),那是否就不需要考慮集算器了呢?我覺(jué)得倒也未必……說(shuō)實(shí)話(huà),之前舉例的這種分類(lèi)后求平均值,太幼兒園了……根本無(wú)法體現(xiàn)出多少差別。所以下面咱就算個(gè)稍微復(fù)雜一點(diǎn)的:計(jì)算一下在至少連漲三天的股票中能達(dá)到至少連漲四天的股票的比例吧。
先看看一組原始數(shù)據(jù):
還是先上集算器的代碼,其實(shí)嚴(yán)格來(lái)講整段代碼可以縮成一大行(不過(guò)感覺(jué)太賴(lài)皮就不做了)。
A | |
1 | =file(“E:/Stock.xlsx”).importxls@t().sort(Date).group(Company) |
2 | =A1.((a=0,~.max(a=if(Price>Price[-1],a+1,0)))) |
3 | =string(A2.count(~>=4)/A2.count(~>=3),”0.00%”) |
思路很簡(jiǎn)單,按日期排序再按股票分組,然后計(jì)算出每支股票最長(zhǎng)上漲了多少天,再看這個(gè)值不低于3或不低于4的股票個(gè)數(shù)就完了,只是寫(xiě)出連漲的邏輯會(huì)有些考驗(yàn),集算器有很好的跨行引用機(jī)制,就不在話(huà)下了。
計(jì)算結(jié)果嘛,因?yàn)閿?shù)據(jù)不多,有耐心的可以心算驗(yàn)算一下
再看看python解決此題需要的代碼(已做了盡量的簡(jiǎn)化,若還有不足歡迎指導(dǎo))
- import pandas as pd
- def iterate(col):
- prev = 0;
- res = 0;
- val = 0;
- for curr in col:
- if curr – prev > 0:
- res += 1;
- else:
- res = 0;
- prev = curr;
- if val < res:
- val = res;
- return val;
- data = pd.read_excel(‘E:/Stock.xlsx’,sheet_name=0).sort_values(‘Date’).groupby(‘Company’)[‘Price’].apply(iterate);
- print(‘%.2f%%’ % (data[data>=4].count()/data[data>=3].count() * 100));
基本思路其實(shí)都差不多,只是python沒(méi)有太好的跨行引用機(jī)制,得搞個(gè)自定義函數(shù)才能實(shí)現(xiàn)這種略繁瑣的邏輯,比較適合遇到問(wèn)題喜歡DIY的同學(xué)們。計(jì)算結(jié)果因?yàn)槎家粯泳筒毁N出來(lái)了
當(dāng)然,也不是說(shuō)集算器什么方面都比python強(qiáng),比如來(lái)個(gè)深度學(xué)習(xí)神經(jīng)網(wǎng)絡(luò)啥的,暫時(shí)集算器里還沒(méi)加上這類(lèi)功能(畢竟術(shù)業(yè)有專(zhuān)攻)。總之,遇到大數(shù)據(jù)或感覺(jué)python類(lèi)庫(kù)安裝起來(lái)太麻煩時(shí),不妨考慮一下集算器。