一篇有趣的文章
總第147篇/wupeng
這篇文章是『讀者分享系列』第三篇,這一篇來自wupeng同學(xué),這是他在讀完我的書以后寫的一個(gè) Python 數(shù)據(jù)分析項(xiàng)目,現(xiàn)在他把整體的思路以及實(shí)現(xiàn)代碼分享出來,希望對(duì)你有幫助。
這篇文章實(shí)在是太有趣了,以至于我不知道該用什么標(biāo)題,所以就簡單粗暴用了一篇有趣的文章這個(gè)標(biāo)題。
你還可以看其他讀者系列:
Python中的這幾種報(bào)錯(cuò)你遇到過嗎?
Python報(bào)表自動(dòng)化
00|花園里的驅(qū)蛇者
驅(qū)使Python蟒蛇為自己工作的奇幻之旅
那是一個(gè)尋常的下午,他困了。
"飛碟瓜,最近戰(zhàn)事緊張,多個(gè)植物花園發(fā)生了激烈的戰(zhàn)斗,麻煩你統(tǒng)計(jì)一下上個(gè)月的戰(zhàn)斗成果,看一下植物戰(zhàn)士們的戰(zhàn)斗力有沒有提高。今天晚上向我匯報(bào)。“火炬樹樁交待了這個(gè)任務(wù),就去指揮戰(zhàn)斗了。
"When can I leave work and go home?" 他一遍遍的問自己:“我什么時(shí)候可以下班回家?”
飛碟瓜還沒有把工作做完,而這導(dǎo)致他目前無法下班。怎么辦呢? ?向日葵老師發(fā)來微信了,剛好問一下她。
后來,經(jīng)過一個(gè)月的學(xué)習(xí),飛碟瓜成為了數(shù)據(jù)分析的熟練工。他偶爾還是會(huì)想起那個(gè)令他絕望的下午。
以前,他每天的工作,就是數(shù)據(jù)的羅列,報(bào)表的生成,以及分類匯總,他曾經(jīng)是植物花園里,遠(yuǎn)近聞名的”表哥”。但是,從那個(gè)下午開始,他開始嘗試,把一些每月例行的重復(fù)工作,寫成腳本文件,讓python蟒蛇來進(jìn)行辦公自動(dòng)化的操作。“這像是一個(gè)奇幻之旅。”飛碟瓜說。
在1996年5月20日,全世界有3000多萬人使用微軟Excel,而且平均每分鐘新增5個(gè)用戶。根據(jù)pythonanywhere.com網(wǎng)站博客文章的估算,世界上大約有180萬至280萬的python程序員。2019年2月印刷的一本《對(duì)比Excel,輕松學(xué)習(xí)Python數(shù)據(jù)分析》引起了這兩個(gè)龐大的用戶群體的熱烈追捧。在這本書里,圍繞數(shù)據(jù)分析的流程,作者數(shù)據(jù)分析師張俊紅先生,詳細(xì)介紹了每個(gè)步聚中,用Excel如何實(shí)現(xiàn),用Python如何實(shí)現(xiàn)。
『?事務(wù)千萬件,流程第一件。不按流程走,返工流眼淚?』。這是向日葵老師反復(fù)強(qiáng)調(diào)的事情,也是飛碟瓜長期工作的經(jīng)驗(yàn)。
現(xiàn)在,飛碟瓜就按照數(shù)據(jù)分析的基本流程,一步步的開始分析了。
01|明確目的
根據(jù)各個(gè)花園上報(bào)的這樣的明細(xì)數(shù)據(jù)
統(tǒng)計(jì)戰(zhàn)斗成果,每月例行填寫下列表格:
| 戰(zhàn)功 | |||||
| 戰(zhàn)斗次數(shù) | |||||
| 每場戰(zhàn)功 |
其中,戰(zhàn)功就是僵尸等級(jí)乘以僵尸數(shù)量。打敗的僵尸越多,打敗的僵尸的等級(jí)越高,戰(zhàn)功越大。
02|熟悉工具
飛碟瓜去這個(gè)網(wǎng)址,下載了Python蟒蛇的集成開發(fā)環(huán)境Anaconda。
然后他念起了咒語:『 天靈靈,地靈靈,Python蟒蛇快顯靈。拿出熊貓工具包,日期時(shí)間包也要。幫我解決大難題,你的好處少不了 』。
Python蟒蛇回答說:『 SyntaxError: invalid character in identifier 』語法錯(cuò)誤:標(biāo)識(shí)符中的字符無效。
向日葵老師提醒道:『 你想驅(qū)使Python蟒蛇幫你干活,必須是你去學(xué)習(xí)蛇語,而不是蟒蛇學(xué)習(xí)咒語。好在蛇語不難學(xué),跟英語挺相似的 』。
飛碟瓜無奈的打開了Anaconda里面的jupyter notebook軟件,給大蟒蛇下達(dá)了指令。
from?datetime?import?datetime import?pandas?as?pd03|獲取數(shù)據(jù)
飛碟瓜繼續(xù)下達(dá)指令:
蟒蛇,戰(zhàn)斗成果的原始數(shù)據(jù)文件的位置,放在了"d:\documents\temp1\"的文件夾里面,文件名字叫做"battle.xlsx"。
有一個(gè)叫做“戰(zhàn)斗日期”的列,是記錄日期的,你可不要以為是數(shù)值,你拿出你的日期時(shí)間工具包,把它處理一下,要保證理解為日期的值。
文件的編碼是GBK編碼的,別搞亂碼了。
把文件取出之后,放在一個(gè)DataFrame數(shù)據(jù)框架里面,并且起個(gè)名字叫做data“
(DataFrame是由一組數(shù)據(jù)與一對(duì)索引(行索引和列索引)組成的表格型數(shù)據(jù)結(jié)構(gòu))
04|熟悉數(shù)據(jù)
『 弄好了嗎 』,顯示dataframe的前五行數(shù)據(jù),給我看看吧。
print?(data.head())蟒蛇回復(fù):
??僵尸ID?????僵尸類別ID??戰(zhàn)場編號(hào)??僵尸等級(jí)??僵尸數(shù)量???????戰(zhàn)斗日期?????????????????????戰(zhàn)斗ID 0??30006206??915000003??CDNL?????4?????????1?????????????2018-01-01??????????20170103CDLG000210052759 1??30163281??914010000??CDNL?????1?????????2?????????????2018-01-02??????????20170103CDLG000210052759 2??30200518??922000000??CDNL?????2?????????1?????????????2018-01-03??????????20170103CDLG000210052759 3??29989105??922000000??CDNL?????1?????????3?????????????2018-01-04??????????20170103CDLG000210052759 4??30179558??915000100??CDNL?????4?????????1?????????????2018-01-05??????????20170103CDLG00021005275905|處理數(shù)據(jù)
看一下是否有缺失值,各個(gè)列的數(shù)據(jù)類型是什么
print?(data.info())蟒蛇應(yīng)答:
<class?'pandas.core.frame.DataFrame'> RangeIndex:?3478?entries,?0?to?3477 Data?columns?(total?7?columns): 僵尸ID??????3478?non-null?int64 僵尸類別ID????3478?non-null?int64 戰(zhàn)場編號(hào)??????3478?non-null?object 僵尸等級(jí)??????3478?non-null?int64 僵尸數(shù)量??????3478?non-null?int64 戰(zhàn)斗日期??????3478?non-null?datetime64[ns] 戰(zhàn)斗ID??????3478?non-null?object dtypes:?datetime64[ns](1),?int64(4),?object(2) memory?usage:?190.3+?KB None飛碟瓜看了一下,注意到
所有的列都是3478行,全都沒有空值(non-null)
而且”戰(zhàn)斗日期"的數(shù)據(jù)格式為datetime64[ns],符合要求。
查一下是否有異常的數(shù)值,比方說,僵尸數(shù)量為負(fù)數(shù),僵尸等級(jí)大于5,目前如果存在這類數(shù)據(jù),就屬于異常值。
print(data.describe())蟒蛇回答:
?僵尸ID????????僵尸類別ID?????????僵尸等級(jí)?????????僵尸數(shù)量 count?????3.478000e+03??3.478000e+03??3478.000000??3478.000000 mean??????3.004899e+07??9.214786e+08?????2.526164?????1.478723 std???????7.303804e+04??9.653496e+06?????1.109625?????1.901963 min???????2.998902e+07??9.100000e+08?????1.000000?????1.000000 25%???????2.998915e+07??9.140701e+08?????2.000000?????1.000000 50%???????3.001310e+07??9.220000e+08?????3.000000?????1.000000 75%???????3.010167e+07??9.230000e+08?????4.000000?????2.000000 max???????3.021483e+07??9.600000e+08?????4.000000????45.00000006|分析數(shù)據(jù)
| 戰(zhàn)功=僵尸等級(jí)*僵尸數(shù)量 | |||||
| 戰(zhàn)斗次數(shù)=戰(zhàn)斗ID去重計(jì)數(shù) | |||||
| 每場戰(zhàn)功=戰(zhàn)功/戰(zhàn)斗次數(shù) |
篩選出本月累計(jì)、上月同期、去年同期 這三個(gè)時(shí)間段范圍內(nèi),對(duì)應(yīng)的數(shù)據(jù)框架DataFrame。
This_data=data[(data['戰(zhàn)斗日期']>=datetime(2018,2,1))&(data['戰(zhàn)斗日期']<=datetime(2018,2,28))] Last_data=data[(data['戰(zhàn)斗日期']>=datetime(2018,1,1))&(data['戰(zhàn)斗日期']<=datetime(2018,1,31))] Same_data=data[(data['戰(zhàn)斗日期']>=datetime(2017,2,1))&(data['戰(zhàn)斗日期']<=datetime(2017,2,28))]編寫函數(shù),輸入的參數(shù)為 各個(gè)時(shí)間段的數(shù)據(jù)框架DataFrame, 輸出的值為 戰(zhàn)功,戰(zhàn)斗次數(shù),每場戰(zhàn)功的數(shù)據(jù)。
def?get_month_data(perioddata):contribution=(perioddata['僵尸等級(jí)']*perioddata['僵尸數(shù)量']).sum()number_of_battles=perioddata['戰(zhàn)斗ID'].drop_duplicates().count()s_t=(contribution/number_of_battles)print?(contribution,number_of_battles,s_t)return?(contribution,number_of_battles,s_t)調(diào)用函數(shù),計(jì)算出需要的數(shù)據(jù)
contribution_1,number_of_battles_1,a_n_1=get_month_data(This_data)???#分別計(jì)算本月的戰(zhàn)功,戰(zhàn)斗次數(shù),每場戰(zhàn)功 contribution_2,number_of_battles_2,a_n_2=get_month_data(Last_data)???#分別計(jì)算上月的戰(zhàn)功,戰(zhàn)斗次數(shù),每場戰(zhàn)功 contribution_3,number_of_battles_3,a_n_3=get_month_data(Same_data)???#分別計(jì)算上年同期的戰(zhàn)功,戰(zhàn)斗次數(shù),每場戰(zhàn)功合并三個(gè)時(shí)間段的指標(biāo)到同一個(gè)DataFrame數(shù)據(jù)框架里面
設(shè)定DataFrame的行名稱是['戰(zhàn)功','戰(zhàn)斗次數(shù)','每場戰(zhàn)功']
設(shè)定DataFrame的列名稱為['本月累計(jì)','上月同期','去年同期']
第1行的數(shù)據(jù)項(xiàng)填充為'contribution_1(本月戰(zhàn)功),contribution_2(上月戰(zhàn)功),contribution_3(上年同期戰(zhàn)功)
第2行的數(shù)據(jù)項(xiàng)填充為'number_of_battles_1(本月戰(zhàn)斗次數(shù)),number_of_battles_2(上月戰(zhàn)斗次數(shù)),number_of_battles_3(上年同期戰(zhàn)斗次數(shù))
第3行的數(shù)據(jù)項(xiàng)填充為'a_n_1(本月每場戰(zhàn)功),a_n_2(上月每場戰(zhàn)功),a_n_3(上年同期每場戰(zhàn)功)
增加環(huán)比和同比指標(biāo)。
report['環(huán)比']=report['本月累計(jì)']/report['上月同期']-1 report['同比']=report['本月累計(jì)']/report['去年同期']-1查看數(shù)據(jù),并且導(dǎo)出文件到本地。
print(report) report.to_excel(r'd:\documents\temp1\report.xlsx')蟒蛇回復(fù):
??????本月累計(jì)?上月同期?去年同期?環(huán)比?同比 戰(zhàn)功?????4433?4237?4331?0.046259?0.023551 戰(zhàn)斗次數(shù)?343?315?262?0.088889?0.30916 每場戰(zhàn)功?12.9242?13.45079?16.53053?-0.03915?-0.21816從此以后,每當(dāng)有其他的植物花園發(fā)送來戰(zhàn)斗情況表的時(shí)候,飛碟瓜只需要召喚一下,Python蟒蛇就會(huì)刷刷刷的算好需要的數(shù)據(jù),貼心地生成Excel文件。飛碟瓜就再也不用加班啦。
07|完整的Python代碼
from?datetime?import?datetime import?pandas?as?pd data=pd.read_excel(r'd:\documents\temp1\battle.xlsx',parse_dates=['戰(zhàn)斗日期'],encoding='gbk') print?(data.head()) print?(data.info()) print(data.describe()) def?get_month_data(perioddata):contribution=(perioddata['僵尸等級(jí)']*perioddata['僵尸數(shù)量']).sum()number_of_battles=perioddata['戰(zhàn)斗ID'].drop_duplicates().count()s_t=(contribution/number_of_battles)print?(contribution,number_of_battles,s_t)return?(contribution,number_of_battles,s_t) This_data=data[(data['戰(zhàn)斗日期']>=datetime(2018,2,1))&(data['戰(zhàn)斗日期']<=datetime(2018,2,28))] Last_data=data[(data['戰(zhàn)斗日期']>=datetime(2018,1,1))&(data['戰(zhàn)斗日期']<=datetime(2018,1,31))] Same_data=data[(data['戰(zhàn)斗日期']>=datetime(2017,2,1))&(data['戰(zhàn)斗日期']<=datetime(2017,2,28))] contribution_1,number_of_battles_1,a_n_1=get_month_data(This_data)???#分別計(jì)算本月的戰(zhàn)功,戰(zhàn)斗次數(shù),每場戰(zhàn)功 contribution_2,number_of_battles_2,a_n_2=get_month_data(Last_data)???#分別計(jì)算上月的戰(zhàn)功,戰(zhàn)斗次數(shù),每場戰(zhàn)功 contribution_3,number_of_battles_3,a_n_3=get_month_data(Same_data)???#分別計(jì)算上年同期的戰(zhàn)功,戰(zhàn)斗次數(shù),每場戰(zhàn)功 report=pd.DataFrame([[contribution_1,contribution_2,contribution_3],[number_of_battles_1,number_of_battles_2,number_of_battles_3],[a_n_1,a_n_2,a_n_3]],columns=['本月累計(jì)','上月同期','去年同期'],index=['戰(zhàn)功','戰(zhàn)斗次數(shù)','每場戰(zhàn)功']) report['環(huán)比']=report['本月累計(jì)']/report['上月同期']-1 report['同比']=report['本月累計(jì)']/report['去年同期']-1 print(report) report.to_excel(r'd:\documents\temp1\report.xlsx')關(guān)于作者
領(lǐng)英:?
http://www.linkedin.com/in/wupeng19962000/
微信:
w13642665267
總結(jié)
- 上一篇: 可让 Win11 任务栏图标不合并的全新
- 下一篇: 5月碎碎念