热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

crosstab汇总_Pandas的crosstab函数

介绍我很喜欢DataCamp上的“Seaborn中间数据可视化”(IntermediateDataVisualizationwithSeaborn)这个课程。它教给新手非常棒的图表

介绍

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

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

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

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

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

目录
  • 简介
  • 设置
  • crosstab基础知识
  • Pandas crosstab()与pivot_table()和groupby()的比较
  • Pandas crosstab()的进一步定制
  • Pandas crosstab(),多个组

设置

# 导入必要的库import pandas as pdimport matplotlib.pyplot as pltimport seaborn as snsimport numpy as np# 忽略警告import warningswarnings.filterwarnings('ignore')# 启用多单元输出from IPython.core.interactiveshell import InteractiveShellInteractiveShell.ast_node_interactivity = 'all'

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

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

e6d9bfdff38f6da2f999fcf2f1506f32.png

crosstab()基础知识

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

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

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

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

b853ec8cc999955ffbfcdd7d46ddf53c.png

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

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

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

dbf95c6111564a138ee0e94de7a35aff.png

现在,每个单元格包含了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');

0be25fdbcb35b16ac390ea19eefe6ab4.png

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 colorIdeal D 2629.0 E 2598.0 F 3375.0 G 3721.0 H 3889.0 I 4452.0 J 4918.0Premium D 3631.0 E 3539.0 F 4325.0 G 4501.0 H 5217.0 I 5946.0 J 6295.0Very Good D 3470.0 E 3215.0 F 3779.0 G 3873.0 H 4535.0 I 5256.0 J 5104.0Good D 3405.0 E 3424.0 F 3496.0 G 4123.0 H 4276.0 I 5079.0 J 4574.0Fair D 4291.0 E 3682.0 F 3827.0 G 4239.0 H 5136.0 I 4685.0 J 4976.0Name: 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)

dbf95c6111564a138ee0e94de7a35aff.png

以上是pivot_table的输出

dbf95c6111564a138ee0e94de7a35aff.png

以上是crosstab的输出

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

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

dbf95c6111564a138ee0e94de7a35aff.png

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

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

%%timeitdiamonds.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)%%timeitpd.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)%%timeitdiamonds.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%')

36d3efd84e62647c86ba283de5c8db70.png

如果传递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%')

0206bdcfa58930fdc523041c28f488ba.png

以上是按行规范化

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

b7a8dd19fca89197cf6b30dbd89eb34e.png

以上是按列规范化

在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)

b6eb8b23f0686f55e9a8edf760b09243.png

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

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

9a1573d7959bcfb92d4401256dc05b0b.png

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

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

83adb75d74ad1f91cfa65d93336e318c.png

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

Pandas crosstab(),多组

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

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

5d6a8c36785fb5d4c12a144a2aeb0594.png

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

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

f95e5f8255d79f98ac050d5324952bb3.png

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

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

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



推荐阅读
  • 探索CNN的可视化技术
    神经网络的可视化在理论学习与实践应用中扮演着至关重要的角色。本文深入探讨了三种有效的CNN(卷积神经网络)可视化方法,旨在帮助读者更好地理解和优化模型。 ... [详细]
  • Java虚拟机及其发展历程
    Java虚拟机(JVM)是每个Java开发者日常工作中不可或缺的一部分,但其背后的运作机制却往往显得神秘莫测。本文将探讨Java及其虚拟机的发展历程,帮助读者深入了解这一关键技术。 ... [详细]
  • 本文将深入探讨 Unreal Engine 4 (UE4) 中的距离场技术,包括其原理、实现细节以及在渲染中的应用。距离场技术在现代游戏引擎中用于提高光照和阴影的效果,尤其是在处理复杂几何形状时。文章将结合具体代码示例,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 根据官方定义,RxJava是一种用于异步编程和可观察数据流的API。其核心特性在于流式处理能力和丰富的操作符支持。 ... [详细]
  • 本文由公众号【数智物语】(ID: decision_engine)发布,关注获取更多干货。文章探讨了从数据收集到清洗、建模及可视化的全过程,介绍了41款实用工具,旨在帮助数据科学家和分析师提升工作效率。 ... [详细]
  • 本文详细介绍了PHP中几个常用的数组回调函数,包括array_filter、array_map、array_walk和array_reduce。通过具体的语法、参数说明及示例,帮助开发者更好地理解和使用这些函数。 ... [详细]
  • C/C++ 应用程序的安装与卸载解决方案
    本文介绍了如何使用Inno Setup来创建C/C++应用程序的安装程序,包括自动检测并安装所需的运行库,确保应用能够顺利安装和卸载。 ... [详细]
  • SSE图像算法优化系列三:超高速导向滤波实现过程纪要(欢迎挑战)
    自从何凯明提出导向滤波后,因为其算法的简单性和有效性,该算法得到了广泛的应用,以至于新版的matlab都将其作为标准自带的函数之一了&#x ... [详细]
  • 视觉Transformer综述
    本文综述了视觉Transformer在计算机视觉领域的应用,从原始Transformer出发,详细介绍了其在图像分类、目标检测和图像分割等任务中的最新进展。文章不仅涵盖了基础的Transformer架构,还深入探讨了各类增强版Transformer模型的设计思路和技术细节。 ... [详细]
  • 尽管在WPF中工作了一段时间,但在菜单控件的样式设置上遇到了一些基础问题,特别是关于如何正确配置前景色和背景色。 ... [详细]
  • td{border:1pxsolid#808080;}参考:和FMX相关的类(表)TFmxObjectIFreeNotification ... [详细]
  • OBS Studio自动化实践:利用脚本批量生成录制场景
    本文探讨了如何利用OBS Studio进行高效录屏,并通过脚本实现场景的自动生成。适合对自动化办公感兴趣的读者。 ... [详细]
  • 微信小程序开发指南:创建动态电影选座界面
    本文详细介绍如何在微信小程序中实现一个动态且可视化的电影选座组件,提高用户体验。通过合理的布局和交互设计,使用户能够轻松选择心仪的座位。 ... [详细]
  • 本文探讨了一种算法问题,即如何高效地将数组中的所有元素向右移动指定数量的位置。提供了详细的示例和解决方案。 ... [详细]
  • 深入浅出C语言指针
    指针是C语言中极其重要的数据类型,广泛应用于各种数据结构的表示、数组和字符串的操作以及内存地址的处理。本文将通过实例详细解析指针的基本概念及其应用。 ... [详细]
author-avatar
____洋果子
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有