我們在做數(shù)據(jù)分析的時候,可能經(jīng)常會碰到分組統(tǒng)計匯總的情況,現(xiàn)成的工具和開放式的編程語言可以為我們完成分析任務(wù)提高效率。 對于很多不會編程的分析員來說,可能習(xí)慣了用Excel等工具來幫助他們達(dá)到匯總分析的目的。雖然效果也不錯,但過程相對繁瑣,而且局限太大,只能在工具所能提供的功能下完成特定分析。 對于一些腦洞大開,追求思想自由的用戶來說,那就只能尋求更開放的編程語言才能實現(xiàn)飛一般的感覺了。 pandas提供了幾種分析和匯總數(shù)據(jù)的函數(shù),比如gourpby,pivot_table和crosstab,可以說功能強大,十分優(yōu)秀,是您居家旅行,行走江湖殺人滅口的必備工具。 但有時候工具多也不一定是好事,用的時候想不起來,想的起來又不知道怎么用,腦子容易亂。其實,主要還是要對各個函數(shù)了了分明,熟練在心。 今天給大家介紹一下交叉制表統(tǒng)計crosstab,我們用一個例子來完成講解。 數(shù)據(jù)準(zhǔn)備 這里用一個簡單的例子來完成crosstab的實現(xiàn),比如說有一個分析需求:按地域和上市類型統(tǒng)計出上市公司數(shù)量和占比情況。我們知道,每個省都有不同行業(yè)的上市公司,有的是在主板上市,有的在中小板,也有的在創(chuàng)業(yè)板,那每個省的這些上市公司的數(shù)量和占比,能不能用一行代碼就完成匯總分析? 我們先來準(zhǔn)備原始數(shù)據(jù),這里通過Tushare的API完成數(shù)據(jù)的調(diào)取。 import tushare as ts (請在源代碼處往左滑動,可以查看全部代碼,下同) Tushare數(shù)據(jù)的具體使用方法請參考?xì)v史文章《開啟Pro體驗的正確打開方式》。 通過stock_basic接口,我們可以調(diào)取上市公司基礎(chǔ)數(shù)據(jù),這里只取了股票代碼、股票名稱、所在地域,所屬行業(yè)和上市日期這幾個字段。 截取頭部幾行數(shù)據(jù)顯示如下: 簡單實現(xiàn) 首先來實現(xiàn)簡單交叉匯總,我們需要導(dǎo)入pandas包,然后調(diào)用crosstab函數(shù)。 import pandas as pd 可以看到,一段短短的簡單代碼,實現(xiàn)了匯總統(tǒng)計。其實,我們也可以用pandas的gourpby和pivot_table來實現(xiàn),哪個簡單哪個好記,一目了然。 groupby: df.groupby(['area', 'market'])['market'].count().unstack().fillna(0) pivot_table: df.pivot_table(index='area', columns='market', aggfunc={'market':len}, fill_value=0) 總體來說,還是crosstab更容易實現(xiàn)我們預(yù)設(shè)的需求。 深入了解 實現(xiàn)了簡單的交叉制表后,我們來看看如何提升統(tǒng)計效果,很容易想到的是“小計”功能,只要增加參數(shù),就可以實現(xiàn)橫豎合計的功能。 pd.crosstab(df.area, df.market, margins=True, margins_name=u'合計') 另外,我們可能會想到每個地域上市公司的平均市盈率情況(或行業(yè)市盈率,請用戶參考以下方法自行實現(xiàn)行業(yè)平均市盈率統(tǒng)計)。 先把PE數(shù)據(jù)整合到原始數(shù)據(jù)中來, 取當(dāng)前(2018-10-10)PE數(shù)據(jù): pedata = pro.daily_basic(trade_date='20181010')[['ts_code','pe']].set_index('ts_code') 合并成新數(shù)據(jù)集: withpe = df.set_index('ts_code').merge(pes, left_index=True, right_index=True, how='left') 分省分市場的平均市盈率: pd.crosstab(withpe.area, withpe.market, values=withpe.pe, aggfunc='mean').round(0) 還有一個分析項,比如數(shù)量占比情況,用crosstab也非常容易實現(xiàn)。我們可以看一下每個省上市公司的在整個市場的占比情況。 全市場占比: pd.crosstab(df.area, df.market, normalize=True) 拿上海的中小板來舉例,占比為30/3551=0.008448 省份中各類市場上市公司占比(即按行統(tǒng)計): pd.crosstab(df.area, df.market, normalize='index') 按市場各省上市公司占比(即按列統(tǒng)計): pd.crosstab(df.area, df.market, normalize='columns') 最后,我們可能需要更多細(xì)分的統(tǒng)計,比如各省市各行業(yè)所上主板、中小板、創(chuàng)業(yè)板的統(tǒng)計數(shù)據(jù),通過類似groupby的方式實現(xiàn)也是非常方便。 pd.crosstab(df.area, [df.industry,df.market]) 數(shù)據(jù)可視化 完成統(tǒng)計后,我們可能還需要展示出來,可視化是必不可少的,這里只舉一個簡單的例子,更多可視化方案請參閱本公眾號歷史文章。 import seaborn as sns |
|