盘一盘 Python 特别篇 16 - Cross Table

盘一盘 Python 特别篇 16 - Cross Table_第1张图片

本文含 2573 16 图表截屏

建议阅读 14 分钟

我的 Python 进阶版课程马上要出了

星期五发推文,敬请关注

本文是 Python 系列的特别篇的第十六篇

  • 特别篇 1 - PyEcharts TreeMap

  • 特别篇 2 - 面向对象编程

  • 特别篇 3 - 两大利「器」

  • 特别篇 4 - 装饰器

  • 特别篇 5 - Sklearn 0.22

  • 特别篇 6 - Jupyter Notebook

  • 特别篇 7 - 格式化字符串

  • 特别篇 8 - 正则表达式

  • 特别篇 9 - 正则表达式实战

  • 特别篇 10 - 错误类型

  • 特别篇 11 - 异常处理

  • 特别篇 12 - Collection

  • 特别篇 13 - Matplotlib Animation

  • 特别篇 14 - All 和 Any

  • 特别篇 15 - 透视表 Pivot Table

  • 特别篇 16 - 交叉表 Cross Table

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

初探数据

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

loan = pd.read_csv('Loan Data.csv')
loan.head(3).append(loan.tail(2))

盘一盘 Python 特别篇 16 - Cross Table_第2张图片

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

loan.info()

盘一盘 Python 特别篇 16 - Cross Table_第3张图片

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

按贷款种类统计个数

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

pd.crosstab( index=loan['person_home_ownership'], 
             columns=loan['loan_status'] )

盘一盘 Python 特别篇 16 - Cross Table_第4张图片

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

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

pd.pivot_table( loan, index='person_home_ownership',
                      columns='loan_status',
                      aggfunc={'loan_status':len},
                      fill_value=0 )

盘一盘 Python 特别篇 16 - Cross Table_第5张图片

按贷款评级统计个数

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

pd.crosstab( index=loan['loan_grade'], 
             columns=loan['loan_status'], 
             margins=True, 
             margins_name='Total' )

盘一盘 Python 特别篇 16 - Cross Table_第6张图片

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

按贷款种类计算利率均值

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

pd.crosstab( index=loan['person_home_ownership'], 
             columns=loan['loan_status'],
             values=loan['loan_int_rate'], 
             aggfunc='mean').round(2)

盘一盘 Python 特别篇 16 - Cross Table_第7张图片

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

没有 fill_value 参数

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

pd.crosstab( index=loan['person_home_ownership'], 
             columns=loan['loan_grade'],
             values=loan['loan_int_rate'], 
             aggfunc='mean')

盘一盘 Python 特别篇 16 - Cross Table_第8张图片

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

pd.crosstab( index=loan['person_home_ownership'], 
             columns=loan['loan_grade'],
             values=loan['loan_int_rate'], 
             aggfunc='mean').fillna(0)

盘一盘 Python 特别篇 16 - Cross Table_第9张图片

按贷款目的统计百分比

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

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

  • normalized = columns,在列上做标准化

  • normalized = index,在行上做标准化

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

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

pd.crosstab( index=loan['loan_intent'], 
             columns=loan['loan_status'],
             normalize=True ).style.format("{:.2%}")

盘一盘 Python 特别篇 16 - Cross Table_第10张图片

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

pd.crosstab( index=loan['loan_intent'], 
             columns=loan['loan_status'],
             normalize='columns' ).style.format("{:.2%}")

盘一盘 Python 特别篇 16 - Cross Table_第11张图片

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

pd.crosstab( index=loan['loan_intent'], 
             columns=loan['loan_status'],
             normalize='index' ).style.format("{:.2%}")

盘一盘 Python 特别篇 16 - Cross Table_第12张图片

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

盘一盘 Python 特别篇 16 - Cross Table_第13张图片

Stay Tuned!

盘一盘 Python 特别篇 16 - Cross Table_第14张图片

现在京东上有活动到 6 月 18 日截止,扫以下二维码去买书满 100 返 50

你可能感兴趣的:(盘一盘 Python 特别篇 16 - Cross Table)