3C科技 娛樂遊戲 美食旅遊 時尚美妝 親子育兒 生活休閒 金融理財 健康運動 寰宇綜合

Zi 字媒體

2017-07-25T20:27:27+00:00
加入好友
垂死病中驚坐起,沙漠之鷹沒更新!杭州太熱了,沙漠君熱成了狗!流著熱汗跪著把文章寫完,這篇是真的真的乾貨(code)!應該會讓一部分同學不適,恩,老司機要飆車了:0. 如何入門數據分析關注沙漠之鷹的同學一定看過沙漠君寫得很多篇數據分析文章,比如分析房價,車價,預測機動車搖號這些話題。我知道你們想問的問題是:想入門數據分析怎麼做?其實文章中所有的分析都使用了Python和它非常強大的數據分析庫Pandas。一些機器學習和預測的功能則用到了sklearn庫。掌握了這些工具,就能應對絕大多數的分析需求。本文是沙漠君的經驗總結,由於篇幅所限,只貼出了部分代碼案例。下面是針對不同層級的同學給出的一些建議:剛入門,無編程經驗:網上有很多開放的Python學習教程,稍微熟悉之後便可閱讀《用Python做數據分析》,該書通俗易懂,例子容易上手。閱讀本文的主要作用是給你大致的分析流程和概念。有編程基礎: 那太好了,本文能給你大部分問題的解決思路,通過代碼關鍵詞去google一下即可知道它的詳細用法。之後便是反覆地練習了。數據分析老司機: 歡迎互粉GitHub,博客和微信哈紙上得來終覺淺,即使你看了很多書和代碼,也未必比得上多接觸例子多敲一些代碼,三四個中等規模(約一兩百行代碼的)的案例就能讓你有整體的把握。至於數據採集,沙漠之鷹有開源的數據抓取工具Hawk,網上也有眾多如何獲取數據的教程,因此本文不再詳述。系列文章分為三個部分:1) 查詢與統計2) 可視化和高級用法3) 分類和預測(估計會分為幾篇文章)好了,廢話不多說,進入正題。1. 找到好的問題好的問題其實比答案更重要。人認識問題,分為四種級別:我們知道自己知道的(房價在漲)知道自己不知道的(可度量的信息,如房價平均漲幅)不知道自己知道的(如證明搖號系統漏洞)不知道自己不知道的(最有價值,蘊含著最大的機會)沙漠君期待於尋找3-4層級的問題,可是多數情況只能在第1和第2檔上徘徊。當你發現一個問題之後,還需要思考3個問題:我是否找到了一個值得解決的問題?我是否提出了一個足夠好的解決方案我真的想去解決這個問題嗎?最後的動機往往反映了你能解決該問題的最大極限,很多人也許僅僅是完成任務,因此有了一點成果便停滯不前,錯過了最大的金礦。數據的質量比數量更重要,如果不知道什麼樣的數據更重要,即使擁有更多的數據也只會造成嘔吐。數據分析需要專註,需要從紛繁的圖表和信息中找到問題核心。通常來說,人們對變化的指標更感興趣,因此比率和增長幅度比靜態的數據更有說服力。而變化又分長短期,不同維度得出的結論往往全然不同。相關性很好,因果性更佳。有了因果性,便有了改變未來的能力。下圖展示了數據分析的一般流程(圖片來自網路,手機上估計看不清):統計的三大核心:分組(map),聚合(reduce),排序(sort)。它們用的是如此普遍,因此MapReduce管道框架成了數據分析的標準,也非常適合做多機并行化。分組和排序很好理解,聚合指的是對各組內容做求和,分組等。絕大部分數據分析操作,都可以通過查詢,分組,聚合,排序四個元素進行級聯組合進行。因此掌握這四大天王,應付一般的場景就都無問題了。 (這應該是這篇文章最重要的一句話了)2. 查詢和過濾DataFrame是pandas的核心數據結構,可以理解為Excel里的二維矩陣,它更高級,能表達3維或更高維的數據,支持多索引。在內存中存取,效率極高,絕大多數操作都和DataFrame相關。維度為2的DataFrame,行(column)和列(row)的axis分別為0和1。可以針對某些列做索引(index),高維DataFrame是相當少見的。2.1 查詢下面的表展示了Pandas對索引的支持:符號說明例子列值索引df[『房價』] ,df[[『房價』,』車價』]]loc行值索引df.loc[0], df[『2013』:』2015』]iloc行號索引df.iloc[0], df.iloc[2:10]ix行索引df.ix[0], df.ix[2:10]時間也是比較重要的index,比較好用的是Timestamp,接受2016-12-24這種字元串,字元串到時間轉換代碼如下:weather.index= weather[u'日期'].map(lambda x:Timestamp(x))Pandas的索引功能非常強大,補充如下:1) loc也能支持先行后列的查詢:df.loc['20130101':'20130103' , ['A','B']],類似的如iloc2) 個人感覺ix的有些冗餘,和ix和iloc類似所有索引都支持字元串和數組,以及切片(slice)用於指定範圍,索引還能傳遞一個bool類型的lambda表達式,或返回和其shape一致的bool數組。這種用法可以用在過濾上,這非常重要,我們再給幾個例子:2.2 過濾過濾有兩方面需求:找出特定數據進行針對性分析,或針對特定數據做分析,過濾異常值。異常值非常重要,應該細緻分析導致它們產生的原因,如果真是異常值,應該提早過濾,否則做聚合時會嚴重影響結果,如天價的房價。先討論按行過濾:非空過濾,過濾掉col列為空的內容:df=df[!data.col.isnull]字元串過濾:db[db.city.str.contains(u'市')]isin能判斷單元格中的值是否在給定的數組內,若希望對多個列做過濾,Pandas提供了現成的方法df.filter,還支持正則。索引還能進行邏輯操作,實現更複雜的需求。2.3 遍歷有了索引和列操作,為何還要有遍歷?因為遍歷更加靈活,當然性能相對會差一些:函數遍歷目標lambda參數說明map列cellcell最為常見apply列/行列或行axis:不填寫cell1:行,2:列applymapcellcellelement-wise最靈活iterrows行遍歷提供行號見備註iteritems列遍歷提供列名見備註itertuples行遍歷提供index見備註map, apply,applymap是只返回單元格或行列本身的,參數都是lambda,本節假設讀者對python的lambda表達式有足夠的了解。但這樣不能實現如「奇數偶數行做分別作不同處理的需求,則這三個函數就無能為力。因此就有後面iterrows等三個函數。如iterrows,它會將行號和行迭代出來,從而方便自定義邏輯,示例如下:for i,row in data.iterrows: pass2.4 求值和合併一張表可能很難包含所有的信息,因此需要計算新值(求值)或join其他表(合併),但Pandas本身的Join並不好用,經常出錯。如果某個屬性可以通過計算獲得,可對各個列當做變數來處理,由於內部使用了C++和numpy加速,效率遠比for循環更高,下面是處理房價的一個例子:總價/單價,並做小數點截取:table['面積']=np.round(table['總價']*10000/table['單價'])numpy提供了絕大多數常見的函數運算元,能滿足大部分需求。下面是合併:橫向合併(需保證行數一致)- 橫向合併 df = pd.concat([data_train, dummies_Cabin])刪除列 df.drop(['Pclass', 'Name', 'Sex')]縱向合併(join操作)data.merge(right=prop_rates,\how='inner',left_on='Property_Area',\right_index=True, sort=False)如果不加參數,則可以自動通過列名合併。join的參數比較複雜,建議直接參考Pandas官方文檔。3. 分組,排序,聚合排序,分組和聚合的組合都有無數種,這在技術層面不難。但如果要寫報告,避免大而全,因為客戶的注意力很容易浪費在沒有意義的圖表上。將客戶真正關心的搞出來,行業背景分析,用戶畫像,競品監測,銷售行為分析…如果是寫通俗文章,多問幾個人,你想要知道什麼。由於分組是基礎,我們先介紹分組:3.1 分組分組就是按照一個或多個鍵,將數據分為幾個組的過程。你可以直接傳列名做分組,df.groupby('column_name')也可以傳遞相同行數的Series甚至DataFrame。下面的例子是按日期里的年做分組:df2.groupby(df2.日期.map(lambda x:x.year))Pandas也能支持傳遞多個列的數組,除了切片以外,能在索引上使用的基本都能在group,sort上使用,一致性的API上手非常容易。值得注意的是,由於時間索引分組比較困難,例如每五個月一組,可以用針對TimeStamp特定優化的方案,如resample:下面計算了北京按年平均的AQI:db[db.city==u'北京'][u'平均值'].resample('12M').aqi.mean3.2 排序Pandas的排序非常之快,大部分操作都能在瞬間完成。排序分為兩類:對一般數據排序一般排序,直接用sort即可,傳遞lambda,列名或多個列,或長度一致的Series,這與groupby等其他API一致,此處從略。可指定ascending=True|False來指定升序,降序。對分組后數據排序groupby之後的數據,和一般的DataFrame不同,而像個字典(dict)。對鍵排序,需使用sort_index,值排序,需使用sort_values。3.3 聚合聚合可將分組后的數據按需求重新打平。如求每個分組的最大值(max),最小值(min),或數量等,例如:df2.groupby(df2.日期.map(lambda x:x.year)).size我們來寫幾個例子大家說說是什麼意思:car.groupby(car.年月.map(lambda x:x.month)).銷量.sum.plot(kind='bar',title='汽車市場月度銷量匯總')將汽車數據按照月份分組,按銷量求和。然後繪製直方圖:Pandas支持直接將聚合結果繪圖輸出(雖然丑但是方便啊),下一節我們將詳細介紹它的使用細節。這條語句統計了廣西省東風MPV的各車型總體銷量情況,並按數量降序:df[(df.省=='廣西') & (df.車型分類=='MPV') & (df.品牌=='東風')].groupby('車型').size.sort_values(ascending=False)3.4 數據透視表如果我想一次性地針對多種分組方式實行多種聚合策略,有沒有更方便的API? 答案是數據透視表(pivot_table)。Excel也有該功能,異常強大,有了它,一般需求幾乎都能實現。下面是同時按Name rep manager分組,按價格分別以總價和數量聚合,並將空值填為0.pd.pivot_table(df,\index=["Name","Rep","Manager"],\values=["Price"],\aggfunc=[np.sum,len],\fill_value=0)pivot之後,生成的DataFrame是multiindex的,處理起來稍顯繁瑣,用xs可將某個子index的數據「提升」出來,例如:df_pivot.xs(('12AM新坐標',2011))至於更複雜的訪問和採樣,可配合loc和PD.IndexSlice, 可自行查看官方文檔。4. 總結Pandas本身異常強大,功能非常繁雜,筆者僅僅掌握了其中非常小的一部分。但是對於一般的需求都能通過簡單的操作組合出來。API的一致性非常重要,Pandas(包括numpy等)都繼承了Python的優良特性,因此只要能舉一反三,就能進步神速。文章不能太長,否則就沒人看得完了。不過相信我,掌握文中說的用法,基本上就足夠混口飯吃了。因為寫SQL的速度和靈活性是遠遠不及Pandas語法的。下一篇是數據可視化,我們來討論如何做可視化,還有對應的Python庫。有任何問題,歡迎交流。感謝關注沙漠之鷹,歡迎轉發分享。

本文由yidianzixun提供 原文連結

寫了 5860316篇文章,獲得 23313次喜歡
精彩推薦