一行Python代码实现交叉表数据分析
我们在做数据分析的时候,可能经常会碰到分组统计汇总的情况,现成的工具和开放式的编程语言可以为我们完成分析任务提高效率。
对于很多不会编程的分析员来说,可能习惯了用Excel等工具来帮助他们达到汇总分析的目的。虽然效果也不错,但过程相对繁琐,而且局限太大,只能在工具所能提供的功能下完成特定分析。
对于一些脑洞大开,追求思想自由的用户来说,那就只能寻求更开放的编程语言才能实现飞一般的感觉了。
pandas提供了几种分析和汇总数据的函数,比如gourpby,pivot_table和crosstab,可以说功能强大,十分优秀,是您居家旅行,行走江湖杀人灭口的必备工具。
但有时候工具多也不一定是好事,用的时候想不起来,想的起来又不知道怎么用,脑子容易乱。其实,主要还是要对各个函数了了分明,熟练在心。
今天给大家介绍一下交叉制表统计crosstab,我们用一个例子来完成讲解。
私信回复小编【PDF】可获取小编精心整理的电子书一套
数据准备
这里用一个简单的例子来完成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)