一行Python程式碼實現交叉表資料分析!
我們在做資料分析的時候,可能經常會碰到分組統計彙總的情況,現成的工具和開放式的程式語言可以為我們完成分析任務提高效率。
對於很多不會程式設計的分析員來說,可能習慣了用Excel等工具來幫助他們達到彙總分析的目的。雖然效果也不錯,但過程相對繁瑣,而且侷限太大,只能在工具所能提供的功能下完成特定分析。
對於一些腦洞大開,追求思想自由的使用者來說,那就只能尋求更開放的程式語言才能實現飛一般的感覺了。
pandas提供了幾種分析和彙總資料的函式,比如gourpby,pivot_table和crosstab,可以說功能強大,十分優秀,是您居家旅行,行走江湖殺人滅口的必備工具。
但有時候工具多也不一定是好事,用的時候想不起來,想的起來又不知道怎麼用,腦子容易亂。其實,主要還是要對各個函數了了分明,熟練在心。
今天給大家介紹一下交叉製表統計crosstab,我們用一個例子來完成講解。
資料準備
這裡用一個簡單的例子來完成crosstab的實現,比如說有一個分析需求:按地域和上市型別統計出上市公司數量和佔比情況。我們知道,每個省都有不同行業的上市公司,有的是在主機板上市,有的在中小板,也有的在創業板,那每個省的這些上市公司的數量和佔比,能不能用一行程式碼就完成彙總分析?
我們先來準備原始資料,這裡通過Tushare的API完成資料的調取。
import tushare as ts pro = ts.pro_api('your token') df = pro.stock_basic(exchange_id='', list_status='L', fields='ts_code,name,area,industry,list_date')
(請在原始碼處往左滑動,可以檢視全部程式碼,下同)
Tushare資料的具體使用方法請參考歷史文章《開啟Pro體驗的正確開啟方式》。
通過stock_basic介面,我們可以調取上市公司基礎資料,這裡只取了股票程式碼、股票名稱、所在地域,所屬行業和上市日期這幾個欄位。
擷取頭部幾行資料顯示如下:
簡單實現
首先來實現簡單交叉彙總,我們需要匯入pandas包,然後呼叫crosstab函式。
import pandas as pd data = pd.crosstab(df.area, df.market)
可以看到,一段短短的簡單程式碼,實現了彙總統計。其實,我們也可以用pandas的gourpby和pivot_table來實現,哪個簡單哪個好記,一目瞭然。
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更容易實現我們預設的需求。
深入瞭解
實現了簡單的交叉製表後,我們來看看如何提升統計效果,很容易想到的是“小計”功能,只要增加引數,就可以實現橫豎合計的功能。
pd.crosstab(df.area, df.market, margins=True, margins_name=u'合計')
另外,我們可能會想到每個地域上市公司的平均市盈率情況(或行業市盈率,請使用者參考以下方法自行實現行業平均市盈率統計)。
先把PE資料整合到原始資料中來,
取當前(2018-10-10)PE資料:
pedata = pro.daily_basic(trade_date='20181010')[['ts_code','pe']].set_index('ts_code')
合併成新資料集:
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)
還有一個分析項,比如數量佔比情況,用crosstab也非常容易實現。我們可以看一下每個省上市公司的在整個市場的佔比情況。
全市場佔比:
pd.crosstab(df.area, df.market, normalize=True)
拿上海的中小板來舉例,佔比為30/3551=0.008448
省份中各類市場上市公司佔比(即按行統計):
pd.crosstab(df.area, df.market, normalize='index')
按市場各省上市公司佔比(即按列統計):
pd.crosstab(df.area, df.market, normalize='columns')
最後,我們可能需要更多細分的統計,比如各省市各行業所上主機板、中小板、創業板的統計資料,通過類似groupby的方式實現也是非常方便。
pd.crosstab(df.area, [df.industry,df.market])
資料視覺化
完成統計後,我們可能還需要展示出來,視覺化是必不可少的,這裡只舉一個簡單的例子,更多視覺化方案請參閱本公眾號歷史文章。
import seaborn as sns sns.heatmap(pd.crosstab(df.area, df.market), annot=True, fmt="d", linewidths=.5,ax=ax, cbar=False)