作者|Bex T. 编译|VK 来源|Towards Datas Science

介绍

我很喜欢DataCamp上的“Seaborn中间数据可视化”(Intermediate Data Visualization with Seaborn)这个课程。它教给新手非常棒的图表和方法。但说到热图,课程的老师不知怎么地引入了一个全新的pandas函数crosstab。然后,很快说:“crosstab是一个计算交叉表的有用函数…”

我就在那里不理解了。显然,我的第一反应是查看函数的文档。我刚开始觉得我可以处理Matplotlib的任何文档,但是…我错了。.

在我练习之后,我知道这是别人也会挣扎的事情。所以,我在这里写了一整篇文章。

在本文的最后一部分中,我讨论了为什么有些课程不教你像crosstab这样的高级函数。因为如果不在具体的环境下很难使用这样的函数,同时又保持示例的初学者级别。

此外,大多数课程使用小型或玩具数据集。在更复杂的数据科学环境中,这些复杂函数的好处更为明显,并且经常被更有经验的pandas用户使用。

在这篇文章中,我将教你如何使用crosstab以及如何在其他类似函数中选择它。

目录

  • 简介

  • 设置

  • crosstab基础知识

  • Pandas crosstab()与pivot_table()和groupby()的比较

  • Pandas crosstab()的进一步定制

  • Pandas crosstab(),多个组

你可以在这个GitHub repo上下载本文的notebook:https://github.com/BexTuychiev/medium_stories/tree/master/hardest_of_pandas2

设置

# 导入必要的库
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np# 忽略警告
import warnings
warnings.filterwarnings('ignore')# 启用多单元输出
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = 'all'

对于示例数据,我将使用Seaborn内置的diamonds数据集。它足够大,并且有一些可以用crosstab()的变量:

diamonds = sns.load_dataset('diamonds')
diamonds.head()

crosstab()基础知识

与许多计算分组汇总统计信息的函数一样,crosstab()可以处理分类数据。它可用于将两个或多个变量分组,并为每组的给定值执行计算。当然,使用groupby()或pivot_table()可以执行此类操作,但正如我们稍后将要看到的,crosstab()为你的日常工作流程带来了许多好处。

函数接受两个或多个列表、pandas series 或dataframe,默认情况下返回每个组合的频率。我总是喜欢从一个例子开始,这样你可以更好地理解定义,然后我将继续解释语法。

crosstab()总是返回一个数据帧,下面是一个例子。dataframe是diamonds中两个变量的交叉表:cut和color。交叉表表示取一个变量,将其组显示为index,取另一个变量,将其组显示为columns。

pd.crosstab(index=diamonds['cut'], columns=diamonds['color'])

语法相当简单。index用于对变量进行分组,并将其显示为index(行),对于列也是如此。如果没有给定聚合函数,则每个单元格将计算每个组合中的观察数。例如,左上角的单元格告诉我们,有2834颗颜色代码为D而且是理想切割的钻石,。

接下来,我们要查看每个组合的平均价格。crosstab()提供values参数来引入第三个要聚合的数值变量:

pd.crosstab(index=diamonds['cut'],columns=diamonds['color'],values=diamonds['price'],aggfunc=np.mean).round(0)

现在,每个单元格包含了cut和color组合的平均价格。为了说明我们要计算平均价格,我们将price列传递给values。请注意,始终必须同时使用values和aggfunc。否则,你将得到一个错误。我还使用round()将答案四舍五入。

尽管它有点高级,但是当你将crosstab()表传递到seaborn的热图中时,你将充分利用crosstab()表的优点。让我们在热图中看到上表:

cross = pd.crosstab(index=diamonds['cut'],columns=diamonds['color'],values=diamonds['price'],aggfunc=np.mean).round(0)
sns.heatmap(cross, cmap='rocket_r', annot=True, fmt='g');

seaborn可以自动将crosstab()表转换为热图。我将注释设置为True,并用颜色条显示热图。seaborn还为列和索引名添加了样式(fmt='g' 将数字显示为整数而不是科学计数)。

热图更容易解释。你不想让你的最终用户看到一张满是数字的表格。因此,我将在需要时将每个crosstab()结果放入热图中。为了避免重复,我创建了一个有用的函数:

def plot_heatmap(cross_table, fmt='g'):fig, ax = plt.subplots(figsize=(8, 5))sns.heatmap(cross_table,annot=True,fmt=fmt,cmap='rocket_r',linewidths=.5,ax=ax)plt.show();

Pandas crosstab()与pivot_table()和groupby()的比较

在我们继续讨论更有趣的内容之前,我想我需要澄清计算分组摘要统计的三个函数之间的区别。

我在本文的第一部分介绍了pivot_table()和groupby()的区别。对于crosstab(),这三者之间的区别在于语法和结果的形状。让我们使用这三种方法计算:

# 使用 groupby()
>>> diamonds.groupby(['cut', 'color'])['price'].mean().round(0)cut        color
Ideal      D        2629.0E        2598.0F        3375.0G        3721.0H        3889.0I        4452.0J        4918.0
Premium    D        3631.0E        3539.0F        4325.0G        4501.0H        5217.0I        5946.0J        6295.0
Very Good  D        3470.0E        3215.0F        3779.0G        3873.0H        4535.0I        5256.0J        5104.0
Good       D        3405.0E        3424.0F        3496.0G        4123.0H        4276.0I        5079.0J        4574.0
Fair       D        4291.0E        3682.0F        3827.0G        4239.0H        5136.0I        4685.0J        4976.0
Name: price, dtype: float64# 使用 pivot_table()
diamonds.pivot_table(values='price',index='cut',columns='color',aggfunc=np.mean).round(0)
# 使用 crosstab()
pd.crosstab(index=diamonds['cut'],columns=diamonds['color'],values=diamonds['price'],aggfunc=np.mean).round(0)

以上是pivot_table的输出

以上是crosstab的输出

我想你已经知道你最喜欢的了。grouppy()返回一个序列,而另两个返回相同的数据帧。但是,可以将groupby系列转换为相同的数据帧,如下所示:

grouped = diamonds.groupby(['cut', 'color'])['price'].mean().round(0)
grouped.unstack()

如果你不了解pivot_table()和unstack()的语法,我强烈建议你阅读本文的第一部分。

说到速度,crosstab()比pivot_table()快,但都比groupby()慢得多:

%%timeit
diamonds.pivot_table(values='price',index='cut',columns='color',aggfunc=np.mean)
11.5 ms ± 483 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)%%timeit
pd.crosstab(index=diamonds['cut'],columns=diamonds['color'],values=diamonds['price'],aggfunc=np.mean)
10.8 ms ± 344 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)%%timeit
diamonds.groupby(['cut', 'color'])['price'].mean().unstack()
4.13 ms ± 39.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

如你所见,即使使用unstack()链接,groupby()也比其他两个快3倍。这说明如果你只想分组和计算摘要统计信息,那么应该使用相同的groupby()。当我链接其他方法(如simple round()时,速度差甚至更大。

其余的比较主要是关于pivot_table()和crosstab()。如你所见,这两个函数的结果的形状是相同的。两者之间的第一个区别是crosstab()可以处理任何数据类型。

它可以接受任何类似数组的对象,比如列表、numpy数组、数据帧列(pandas series)。但是,pivot_table()只对dataframe有效。在一个很有帮助的StackOverflow中,我发现如果在数据帧上使用crosstab(),它会在后台调用pivot_table()。

接下来是参数。有些参数只存在于一个参数中,反之亦然。第一个最流行的是crosstab()的normalize。normalize接受以下选项(来自文档):

  • 如果传递了all或True,则将规范化所有值。

  • 如果传递index,将规范化每一行。

  • 如果传递columns,将规范化每个列。

让我们看一个简单的例子:

cross = pd.crosstab(index=diamonds['cut'],columns=diamonds['color'],normalize='all')
plot_heatmap(cross, fmt='.2%')

如果传递all,对于每个单元格,pandas计算总金额的百分比:

# 证明所有值加起来约等于1
>>> pd.crosstab(diamonds['cut'], diamonds['color'], normalize='all').values.sum()1.0000000000000002

如果传递index或columns,则按列或按行执行相同的操作:

cross = pd.crosstab(diamonds['cut'], diamonds['color'], normalize='index')
plot_heatmap(cross, fmt='.2%')

以上是按行规范化

cross = pd.crosstab(diamonds['cut'], diamonds['color'], normalize='columns')
plot_heatmap(cross, fmt='.2%')

以上是按列规范化

在crosstab()中,还可以使用行名和列名直接在函数内更改索引和列名。之后不必手动执行。当我们一次按多个变量分组时,这两个参数非常有用,你将在后面看到。

参数fill_value只存在于pivot_table()中。有时,当你按许多变量分组时,不可避免地会出现不一致。在pivot_table()中,可以使用fill_value将它们更改为自定义值:

diamonds.pivot_table(index='color', columns='cut', fill_value=0)

但是,如果使用crosstab(),则可以通过在dataframe上链接fillna()来实现相同的效果:

pd.crosstab(diamonds['cut'], diamonds['color']).fillna(0)

Pandas crosstab()的进一步定制

crosstab()的另外两个有用参数是margins和margins_name(两者都存在于pivot_table()中)。设置为True时,边界计算每行和每列的和。我们来看一个例子:

pd.crosstab(index=diamonds['cut'], columns=diamonds['clarity'],  margins=True)

pandas自动添加最后一行和最后一列,默认名称为All。margins_name可以控制名字:

pd.crosstab(index=diamonds['cut'],columns=diamonds['clarity'],margins=True,margins_name='Total Number')

右下角的单元格将始终包含观察的总数,或者如果“normalize”设置为True,则为1:

pd.crosstab(index=diamonds['cut'],columns=diamonds['clarity'],margins=True,margins_name='Total Percentage',normalize=True)

请注意,如果将margins设置为True,则热图是无用的。

Pandas crosstab(),多组

对于index和columns参数,可以传递多个变量。结果将是一个具有多级索引的数据帧。这次我们插入所有的分类变量:

pd.crosstab(index=[diamonds['cut'], diamonds['clarity']],columns=diamonds['color'])

对于index,我传递了color和cut。如果我把它们传递给列,结果将是一个包含40列的数据帧。如果你注意的话,多级索引如预期的那样命名为cut和clear。对于存在多级索引或列名的情况,crosstab()有方便的参数来更改它们的名称:

pd.crosstab(index=[diamonds['cut'], diamonds['clarity']],columns=diamonds['color'], rownames=['Diamond Cut', 'Clarity']).head()

传递相应名称的列表,以将索引名称更改为行名称。这个过程对于控制列名的colnames是相同的。

有一件事让我很惊讶,如果你把多个函数传递给aggfunc,pandas就会抛出一个错误。同样,StackOverflow上的伙计们认为这是一个bug,而且已经有6年多没有解决过了。

最后要注意的是,在pivot_table()和crosstab()中,都有一个dropna参数,如果设置为True,则会删除包含所有nan的列或行。

原文链接:https://towardsdatascience.com/meet-the-hardest-functions-of-pandas-part-ii-f8029a2b0c9b

欢迎关注磐创AI博客站: http://panchuang.net/

sklearn机器学习中文官方文档: http://sklearn123.com/

欢迎关注磐创博客资源汇总站: http://docs.panchuang.net/

Pandas的crosstab函数相关推荐

  1. Python使用pandas的crosstab函数计算混淆矩阵并使用Seaborn可视化混淆矩阵实战

    Python使用pandas的crosstab函数计算混淆矩阵并使用Seaborn可视化混淆矩阵实战 目录 Python使用pandas的crosstab函数计算混淆矩阵并使用Seaborn可视化混淆 ...

  2. pandas使用groupby函数计算dataframe数据中每个分组的N个数值的指数权重移动(滚动)平均、例如,计算某公司的多个店铺每N天(5天)的滚动销售额指数权重移动(滚动)平均

    pandas使用groupby函数计算dataframe数据中每个分组的N个数值的指数权重移动(滚动)平均(Exponential Moving Average).例如,计算某公司的多个店铺每N天(5 ...

  3. pandas使用groupby函数计算dataframe数据中每个分组的N个数值的滚动最大值(rolling max)、例如,计算某公司的多个店铺每N天(5天)的滚动销售额最大值

    pandas使用groupby函数计算dataframe数据中每个分组的N个数值的滚动最大值(rolling max).例如,计算某公司的多个店铺每N天(5天)的滚动销售额最大值 目录

  4. pandas使用dropna函数删除dataframe中全是缺失值的数据列(drop columns with all missing values in dataframe)

    pandas使用dropna函数删除dataframe中全是缺失值的数据列(drop columns with all missing values in dataframe) 目录

  5. pandas编写自定义函数计算多个数据列的加和(sum)、使用groupby函数和apply函数聚合计算分组内多个数据列的加和

    pandas编写自定义函数计算多个数据列的加和(sum).使用groupby函数和apply函数聚合计算分组内多个数据列的加和 目录

  6. pandas使用tabulate函数将pandas dataframe以类似于plsql表格的方式打印出来(printing dataframe in tabular format)

    pandas使用tabulate函数将pandas dataframe以类似于plsql表格的方式打印出来(printing dataframe in tabular format) 目录

  7. pandas将列表list插入到dataframe的单元格中、pandas使用read_csv函数读取文件并设置保留数值的前置0( leading zeroes)

    pandas将列表list插入到dataframe的单元格中.pandas使用read_csv函数读取文件并设置保留数值的前置0( leading zeroes) 目录

  8. pandas使用str函数和startswith函数,筛选dataframe中不是(not start with)以特定前缀开头的数据列(selecting columns)

    pandas使用str函数和startswith函数,筛选dataframe中不是(not start with)以特定前缀开头的数据列(selecting columns not begin wit ...

  9. pandas使用nunique函数计算dataframe每个数据列的独特值的个数(count number of unique values in each column of dataframe)

    pandas使用nunique函数计算dataframe每个数据列的独特值的个数(count number of unique values in each column of dataframe) ...

  10. pandas使用groupby函数计算dataframe每个分组对应的数据行的个数(size of each group in dataframe, rows count of group)

    pandas使用groupby函数计算dataframe每个分组对应的数据行的个数(size of each group in dataframe, rows count of group) 目录

最新文章

  1. SP11469 SUBSET - Balanced Cow Subsets(折半搜索+状态压缩)难度⭐⭐⭐⭐★
  2. 直线轨道上声音延迟信号分析
  3. IIS出现server application error,请问怎么解决?
  4. c语言时钟报告,C语言图形时钟课程设计实验报告
  5. 【LeetCode笔记】56. 合并区间(Java、排序)
  6. 每日算法系列【LeetCode 495】提莫攻击
  7. 模板题——容斥原理、博弈论
  8. java节假日算法_java节假日
  9. 14_美年_图形报表,POI报表_运营数据统计_运营数据统计报表导出
  10. linux 不小心删除ls,浅谈Linux系统误删除文件恢复方法
  11. 【C语言-11】Bingou! ~~~~三个数字从大到小排排坐~~
  12. Unity学习2:如何实现个性化渲染平面(图文详细)
  13. python 实现 i18n 多语言国际化
  14. 酷狗音乐能拉进计算机里面吗,手机上的酷狗音乐怎么传到电脑上|苹果手机酷狗音乐怎么传到电脑上|酷狗音乐电脑和手机怎么同步...
  15. 河北工程大学计算机考试题型,2019上半年河北工程大学计算机等级考试报名通知...
  16. 如何幽默的介绍php是撒,终于明白如何幽默介绍自己名字
  17. 中级财管电脑操作不会用计算机,很全面!2018年中级无纸化考试财管公式输入方法及计算器操作说明...
  18. 数据库基本知识(MySql版)
  19. 2020湖南安化黑茶首届汽车摩托车越野争霸赛圆满结束
  20. Flink:四大基石[Time,Window,Checkpoint,State]

热门文章

  1. 网页验证码识别实例VB.NET2019(二)
  2. 独木舟贪心算法c语言,算法:(贪心算法)-独木舟问题
  3. 编译原理|LL(1)语法分析实验
  4. 【调剂】济南大学智能计算与科学计算课题组现接收计算机专业 (学术型) 硕士生调剂...
  5. 量子计算机ai出现意识,人工智能到底会不会出现自我意识?会不会消灭人类?...
  6. 狗熊会python培训班
  7. 百度网盘分享文件已经被取消的解决办法
  8. vs2008中文版 下载
  9. D. Three Religions
  10. 关于火车票12306