当前位置: 首页 > news >正文

笔记:《利用Python进行数据分析》之透视表和交叉表

透视表和交叉表

透视表(pivot table)是各种电子表格程序和其他数据分析软件中一种常见的数据汇总工具。它根据一个或多个键对数据进行聚合,并根据行和列上的分组键将数据分配到各个矩形区域中。在Python和pandas中,可以通过本章所介绍的groupby功能以及(能够利用层次化索引的)重塑运算制作透视表。DataFrame有一个pivot_table方法,此外还有一个顶级的pandas.pivot_table函数。除能为groupby提供便利之外,pivot_table还可以添加分项小计,也叫做margins。

回到小费数据集,假设我想要根据day和smoker计算分组平均数(pivot_table的默认聚合类型),并将day和smoker放到行上:

In [130]: tips.pivot_table(index=['day', 'smoker'])
Out[130]: size       tip   tip_pct  total_bill
day  smoker                                          
Fri  No      2.250000  2.812500  0.151650   18.420000Yes     2.066667  2.714000  0.174783   16.813333
Sat  No      2.555556  3.102889  0.158048   19.661778Yes     2.476190  2.875476  0.147906   21.276667
Sun  No      2.929825  3.167895  0.160113   20.506667Yes     2.578947  3.516842  0.187250   24.120000
Thur No      2.488889  2.673778  0.160298   17.113111Yes     2.352941  3.030000  0.163863   19.190588

可以用groupby直接来做。现在,假设我们只想聚合tip_pct和size,而且想根据time进行分组。我将smoker放到列上,把day放到行上:

In [131]: tips.pivot_table(['tip_pct', 'size'], index=['time', 'day'],.....:                  columns='smoker')
Out[131]: size             tip_pct          
smoker             No       Yes        No       Yes
time   day                                         
Dinner Fri   2.000000  2.222222  0.139622  0.165347Sat   2.555556  2.476190  0.158048  0.147906Sun   2.929825  2.578947  0.160113  0.187250Thur  2.000000       NaN  0.159744       NaN
Lunch  Fri   3.000000  1.833333  0.187735  0.188937Thur  2.500000  2.352941  0.160311  0.163863

还可以对这个表作进一步的处理,传入margins=True添加分项小计。这将会添加标签为All的行和列,其值对应于单个等级中所有数据的分组统计:

In [132]: tips.pivot_table(['tip_pct', 'size'], index=['time', 'day'],.....:                  columns='smoker', margins=True)
Out[132]: size                       tip_pct                    
smoker             No       Yes       All        No       Yes       All
time   day                                                             
Dinner Fri   2.000000  2.222222  2.166667  0.139622  0.165347  0.158916Sat   2.555556  2.476190  2.517241  0.158048  0.147906  0.153152Sun   2.929825  2.578947  2.842105  0.160113  0.187250  0.166897Thur  2.000000       NaN  2.000000  0.159744       NaN  0.159744
Lunch  Fri   3.000000  1.833333  2.000000  0.187735  0.188937  0.188765Thur  2.500000  2.352941  2.459016  0.160311  0.163863  0.161301
All          2.668874  2.408602  2.569672  0.159328  0.163196  0.160803

这里,All值为平均数:不单独考虑烟民与非烟民(All列),不单独考虑行分组两个级别中的任何单项(All行)。

要使用其他的聚合函数,将其传给aggfunc即可。例如,使用count或len可以得到有关分组大小的交叉表(计数或频率):

In [133]: tips.pivot_table('tip_pct', index=['time', 'smoker'], columns='day',.....:                  aggfunc=len, margins=True)
Out[133]: 
day             Fri   Sat   Sun  Thur    All
time   smoker                               
Dinner No       3.0  45.0  57.0   1.0  106.0Yes      9.0  42.0  19.0   NaN   70.0
Lunch  No       1.0   NaN   NaN  44.0   45.0Yes      6.0   NaN   NaN  17.0   23.0
All            19.0  87.0  76.0  62.0  244.0

如果存在空的组合(也就是NA),你可能会希望设置一个fill_value:

In [134]: tips.pivot_table('tip_pct', index=['time', 'size', 'smoker'],.....:                  columns='day', aggfunc='mean', fill_value=0)
Out[134]: 
day                      Fri       Sat       Sun      Thur
time   size smoker                                        
Dinner 1    No      0.000000  0.137931  0.000000  0.000000Yes     0.000000  0.325733  0.000000  0.0000002    No      0.139622  0.162705  0.168859  0.159744Yes     0.171297  0.148668  0.207893  0.0000003    No      0.000000  0.154661  0.152663  0.000000Yes     0.000000  0.144995  0.152660  0.0000004    No      0.000000  0.150096  0.148143  0.000000Yes     0.117750  0.124515  0.193370  0.0000005    No      0.000000  0.000000  0.206928  0.000000
Yes     0.000000  0.106572  0.065660  0.000000
...                      ...       ...       ...       ...
Lunch  1    No      0.000000  0.000000  0.000000  0.181728Yes     0.223776  0.000000  0.000000  0.0000002    No      0.000000  0.000000  0.000000  0.166005Yes     0.181969  0.000000  0.000000  0.1588433    No      0.187735  0.000000  0.000000  0.084246Yes     0.000000  0.000000  0.000000  0.2049524    No      0.000000  0.000000  0.000000  0.138919Yes     0.000000  0.000000  0.000000  0.1554105    No      0.000000  0.000000  0.000000  0.1213896    No      0.000000  0.000000  0.000000  0.173706
[21 rows x 4 columns]

表10-2 pivot_table的选项

交叉表:crosstab

交叉表(cross-tabulation,简称crosstab)是一种用于计算分组频率的特殊透视表。看下面的例子:

In [138]: data
Out[138]:Sample Nationality    Handedness
0       1         USA  Right-handed
1       2       Japan   Left-handed
2       3         USA  Right-handed
3       4       Japan  Right-handed
4       5       Japan   Left-handed
5       6       Japan  Right-handed
6       7         USA  Right-handed
7       8         USA   Left-handed
8       9       Japan  Right-handed
9      10         USA  Right-handed

作为调查分析的一部分,我们可能想要根据国籍和用手习惯对这段数据进行统计汇总。虽然可以用pivot_table实现该功能,但是pandas.crosstab函数会更方便:

In [139]: pd.crosstab(data.Nationality, data.Handedness, margins=True)
Out[139]: 
Handedness   Left-handed  Right-handed  All
Nationality
Japan                  2             3    5
USA                    1             4    5
All                    3             7   10

crosstab的前两个参数可以是数组或Series,或是数组列表。就像小费数据:

In [140]: pd.crosstab([tips.time, tips.day], tips.smoker, margins=True)
Out[140]: 
smoker        No  Yes  All
time   day                
Dinner Fri     3    9   12Sat    45   42   87Sun    57   19   76Thur    1    0    1
Lunch  Fri     1    6    7Thur   44   17   61
All          151   93  244

http://www.mrgr.cn/news/18579.html

相关文章:

  • 开源提示词让LLM更具创造力
  • 模型评价之提升图(Lift Chart)绘制
  • 工厂模式和策略模式的区别,以及java代码示例
  • IPv6的部署会影响现有IPv4网络的运行吗
  • 全新模版|The Sandbox 迎来生存游戏!
  • ET6框架(十三)ET-EUI循环列表及红点树
  • React 创建和嵌套组件
  • [AcWing]-多重背包问题-动态规划
  • ClickHouse 二进制特征值怎么转化为字符串
  • (第四十一天)
  • Mulesoft 开发笔记
  • 2024爆火全网大模型书籍:《从零构建大型语言模型》星标17.8k
  • 《云原生安全攻防》-- K8s攻击案例:高权限Service Account接管集群
  • 海光物理机CPU压测记录
  • 【深度解析】GPT-3.5、GPT-4.0、GPT-4o mini的区别,你了解多少?
  • 改变地址栏的网址链接路径或传参,不刷新当前网页页面
  • 推荐一个非常实用的在线工具网:115工具网----一个提供高效、实用、方便的在线工具集合网站
  • Vue(十三) 路由、路由嵌套、query、param传参、propos、replace属性。编程式路由导航,特有的生命周期函数,路由守卫
  • 华为OD机试 - 猜数字 - 穷举搜索(Java 2024 E卷 100分)
  • 了解Python中如何实现多线程,并讨论GIL的影响