盘一盘 Python 特别篇 16 - Cross Table

2020-06-24 11:36:21 浏览数 (2)

本文含 2573 字,16 图表截屏

建议阅读 14 分钟

交叉表 (cross table) 是透视表的特例,其默认的整合函数是计算个数频率

初探数据

我们拿一个贷款数据举例,首先载入数据,打印出首三行尾两行。

代码语言:javascript复制
loan = pd.read_csv('Loan Data.csv')
loan.head(3).append(loan.tail(2))

info()函数查阅数据信息,有 32,581 条数据,11 条特征和 1 个标签 (loan_status 那列,0 代表未违约,1 代表违约。)

代码语言:javascript复制
loan.info()

在机器学习中,我们通常用其他 11 个特征 (或特征转换) 建立模型来预测贷款的良莠。在选择特征前,用交叉表可以做单变量分析,即看看每个特征下的不同特征值对应的“违约”和“不违约”的贷款个数或比例。

按贷款种类统计个数

用交叉表来统计 person_home_ownership 列每个类别 (MORTGAGE, OTHER, OWN, RENT) 下面贷款状态的个数,0 代表未违约,1 代表违约。

代码语言:javascript复制
pd.crosstab( index=loan['person_home_ownership'], 
             columns=loan['loan_status'] )

从上表可以一下看出 RENT 下面的违约贷款比例很高。

pivot_table() 函数可以等价实现上面用 crosstab() 的产出结果。由于是统计个数,那么整合函数用的是 len

代码语言:javascript复制
pd.pivot_table( loan, index='person_home_ownership',
                      columns='loan_status',
                      aggfunc={'loan_status':len},
                      fill_value=0 )

按贷款评级统计个数

用交叉表来统计 loan_grade 列每个类别 (从 A 到 G) 下面贷款状态的个数,显示总数 (设置 margins=True) 并起名为 Total (设置 margins_name='Total')。

代码语言:javascript复制
pd.crosstab( index=loan['loan_grade'], 
             columns=loan['loan_status'], 
             margins=True, 
             margins_name='Total' )

评级越高,违约贷款比例越低,这不正是评级的含义么。

按贷款种类计算利率均值

除了统计个数,交叉表也能做透视表做的事情。下列是在不同的 person_home_ownership 和 loan_status 下计算贷款利率的均值。

代码语言:javascript复制
pd.crosstab( index=loan['person_home_ownership'], 
             columns=loan['loan_status'],
             values=loan['loan_int_rate'], 
             aggfunc='mean').round(2)

可以看出,违约贷款的利率都比没有违约贷款的利率高。

没有 fill_value 参数

crosstab() 函数中没有 fill_value 参数,如果结果有 NaN 值,只能紧接一个 .fillna() 函数。

代码语言:javascript复制
pd.crosstab( index=loan['person_home_ownership'], 
             columns=loan['loan_grade'],
             values=loan['loan_int_rate'], 
             aggfunc='mean')

在 OTHER 类下没有评级为 G 的贷款,因此显示 NaN。由于 crosstab() 函数返回对象就是一个数据帧 (DataFrame),那么可以用其下的 fillna() 方法将 NaN 用其他值代替,比如下例用 0 值代替 NaN。

代码语言:javascript复制
pd.crosstab( index=loan['person_home_ownership'], 
             columns=loan['loan_grade'],
             values=loan['loan_int_rate'], 
             aggfunc='mean').fillna(0)

按贷款目的统计百分比

上面已经展示交叉表的计数功能,如果最终结果想用频率展示的话,可以设置 normalize 参数,其中

  • normalized = True 或者 all,在所有元素上做标准化
  • normalized = columns,在列上做标准化
  • normalized = index,在行上做标准化

下面在不同的 loan_intent 和 loan_status 下统计贷款状态的百分比。

设置 normalize=True 按元素计算百分比,即所有元素下的百分比加起来等于 100%。

代码语言:javascript复制
pd.crosstab( index=loan['loan_intent'], 
             columns=loan['loan_status'],
             normalize=True ).style.format("{:.2%}")

设置 normalize=columns 按列计算百分比,即在每列的百分比加起来等于 100%。

代码语言:javascript复制
pd.crosstab( index=loan['loan_intent'], 
             columns=loan['loan_status'],
             normalize='columns' ).style.format("{:.2%}")

设置 normalize=index 按行计算百分比,即在每行的百分比加起来等于 100%。

代码语言:javascript复制
pd.crosstab( index=loan['loan_intent'], 
             columns=loan['loan_status'],
             normalize='index' ).style.format("{:.2%}")

总结,一图胜千言!下图可视化 crosstab() 函数的用法。

Stay Tuned!

0 人点赞