Pandas的crosstab函数
作者|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函数相关推荐
- Python使用pandas的crosstab函数计算混淆矩阵并使用Seaborn可视化混淆矩阵实战
Python使用pandas的crosstab函数计算混淆矩阵并使用Seaborn可视化混淆矩阵实战 目录 Python使用pandas的crosstab函数计算混淆矩阵并使用Seaborn可视化混淆 ...
- pandas使用groupby函数计算dataframe数据中每个分组的N个数值的指数权重移动(滚动)平均、例如,计算某公司的多个店铺每N天(5天)的滚动销售额指数权重移动(滚动)平均
pandas使用groupby函数计算dataframe数据中每个分组的N个数值的指数权重移动(滚动)平均(Exponential Moving Average).例如,计算某公司的多个店铺每N天(5 ...
- pandas使用groupby函数计算dataframe数据中每个分组的N个数值的滚动最大值(rolling max)、例如,计算某公司的多个店铺每N天(5天)的滚动销售额最大值
pandas使用groupby函数计算dataframe数据中每个分组的N个数值的滚动最大值(rolling max).例如,计算某公司的多个店铺每N天(5天)的滚动销售额最大值 目录
- pandas使用dropna函数删除dataframe中全是缺失值的数据列(drop columns with all missing values in dataframe)
pandas使用dropna函数删除dataframe中全是缺失值的数据列(drop columns with all missing values in dataframe) 目录
- pandas编写自定义函数计算多个数据列的加和(sum)、使用groupby函数和apply函数聚合计算分组内多个数据列的加和
pandas编写自定义函数计算多个数据列的加和(sum).使用groupby函数和apply函数聚合计算分组内多个数据列的加和 目录
- pandas使用tabulate函数将pandas dataframe以类似于plsql表格的方式打印出来(printing dataframe in tabular format)
pandas使用tabulate函数将pandas dataframe以类似于plsql表格的方式打印出来(printing dataframe in tabular format) 目录
- pandas将列表list插入到dataframe的单元格中、pandas使用read_csv函数读取文件并设置保留数值的前置0( leading zeroes)
pandas将列表list插入到dataframe的单元格中.pandas使用read_csv函数读取文件并设置保留数值的前置0( leading zeroes) 目录
- pandas使用str函数和startswith函数,筛选dataframe中不是(not start with)以特定前缀开头的数据列(selecting columns)
pandas使用str函数和startswith函数,筛选dataframe中不是(not start with)以特定前缀开头的数据列(selecting columns not begin wit ...
- 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) ...
- 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) 目录
最新文章
- SP11469 SUBSET - Balanced Cow Subsets(折半搜索+状态压缩)难度⭐⭐⭐⭐★
- 直线轨道上声音延迟信号分析
- IIS出现server application error,请问怎么解决?
- c语言时钟报告,C语言图形时钟课程设计实验报告
- 【LeetCode笔记】56. 合并区间(Java、排序)
- 每日算法系列【LeetCode 495】提莫攻击
- 模板题——容斥原理、博弈论
- java节假日算法_java节假日
- 14_美年_图形报表,POI报表_运营数据统计_运营数据统计报表导出
- linux 不小心删除ls,浅谈Linux系统误删除文件恢复方法
- 【C语言-11】Bingou! ~~~~三个数字从大到小排排坐~~
- Unity学习2:如何实现个性化渲染平面(图文详细)
- python 实现 i18n 多语言国际化
- 酷狗音乐能拉进计算机里面吗,手机上的酷狗音乐怎么传到电脑上|苹果手机酷狗音乐怎么传到电脑上|酷狗音乐电脑和手机怎么同步...
- 河北工程大学计算机考试题型,2019上半年河北工程大学计算机等级考试报名通知...
- 如何幽默的介绍php是撒,终于明白如何幽默介绍自己名字
- 中级财管电脑操作不会用计算机,很全面!2018年中级无纸化考试财管公式输入方法及计算器操作说明...
- 数据库基本知识(MySql版)
- 2020湖南安化黑茶首届汽车摩托车越野争霸赛圆满结束
- Flink:四大基石[Time,Window,Checkpoint,State]
热门文章
- 网页验证码识别实例VB.NET2019(二)
- 独木舟贪心算法c语言,算法:(贪心算法)-独木舟问题
- 编译原理|LL(1)语法分析实验
- 【调剂】济南大学智能计算与科学计算课题组现接收计算机专业 (学术型) 硕士生调剂...
- 量子计算机ai出现意识,人工智能到底会不会出现自我意识?会不会消灭人类?...
- 狗熊会python培训班
- 百度网盘分享文件已经被取消的解决办法
- vs2008中文版 下载
- D. Three Religions
- 关于火车票12306