首页Python【Python数据分析】5...

【Python数据分析】52.数据聚合和分组操作——数据透视表与交叉表


本系列文章配套代码获取有以下三种途径:

  • 可以在以下网站查看,该网站是使用JupyterLite搭建的web端Jupyter环境,因此无需在本地安装运行环境即可使用,首次运行浏览器需要下载一些配置文件(大约20M):

https://returu.github.io/Python_Data_Analysis/lab/index.html
链接:https://pan.baidu.com/s/1MYkeYeVAIRqbxezQECHwcA?pwd=mnsj 提取码:mnsj
  • 前往GitHub详情页面,单击 code 按钮,选择Download ZIP选项:
https://github.com/returu/Python_Data_Analysis

根据《Python for Data Analysis 3rd Edition》翻译整理

—————————————————–

1.数据透视表:
数据透视表是电子表格程序和其他数据分析软件中常见的数据汇总工具。它通过一个或多个键聚合数据表,将数据排列在一个矩形中,其中一些分组键沿行,一些沿列。 
DataFrame拥有一个pivot_table 方法,还有一个顶层的 pandas.pivot_table 函数。除了为 groupby 提供方便的接口外,pivot_table 还可以添加部分总计,也称为边距(margins)。

pivot_table与之前介绍的pivot相比较,pivot只能简单重塑,而无法对数据进行聚合,如果存在重复数据将会报错。而pivot_tablepivot基础上,还可以对数据进行聚合。

1DataFrame.pivot(self, index=None, columns=None, values=None)
2DataFrame.pivot_table(self, values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, dropna=True, margins_name='All', observed=False)

首先构造一个示例DataFrame数据:

 1>>> df = pd.DataFrame({"style":["one""two""three","one""two""three","one""two""three"],
2...                    "variable":["A","A","A","B","B","B","A","B","A"],
3...                    "label":["No","Yes","No","Yes","No","Yes","No","Yes","Yes"],
4...                    "value1":np.arange(1,10),
5...                    "value2":np.arange(10,19),
6...                    "value3":np.random.standard_normal(9)})
7
8>>> df
9   style variable label  value1  value2    value3
100    one        A    No       1      10 -0.871524
111    two        A   Yes       2      11 -0.239977
122  three        A    No       3      12 -0.504654
133    one        B   Yes       4      13 -0.467207
144    two        B    No       5      14  0.662229
155  three        B   Yes       6      15  0.354248
166    one        A    No       7      16 -0.889782
177    two        B   Yes       8      17 -2.304532
188  three        A   Yes       9      18  0.126101

假设,想要计算一个一张在行方向上按 style 和 label 排列的分组平均值的表,可以通过pivot_table实现,也可以通过droupby实现。

 1>>> df.pivot_table(index=["style","label"])
2             value1  value2    value3
3style label
4one   No        4.0    13.0 -0.880653
5      Yes       4.0    13.0 -0.467207
6three No        3.0    12.0 -0.504654
7      Yes       7.5    16.5  0.240175
8two   No        5.0    14.0  0.662229
9      Yes       5.0    14.0 -1.272254
10
11# 也可以通过 droupby 实现
12>>> df.groupby(["style","label"]).mean()
13             value1  value2    value3
14style label
15one   No        4.0    13.0 -0.880653
16      Yes       4.0    13.0 -0.467207
17three No        3.0    12.0 -0.504654
18      Yes       7.5    16.5  0.240175
19two   No        5.0    14.0  0.662229
20      Yes       5.0    14.0 -1.272254

假设,在行方向上按 style variable 排列的分组,在列方向按 label 分组,只对 value1value2 聚合。

 1>>> df.pivot_table(index=["style","variable"] , columns="label" , values=["value1","value2"])
2               value1      value2
3label              No  Yes     No   Yes
4style variable
5one   A           4.0  NaN   13.0   NaN
6      B           NaN  4.0    NaN  13.0
7three A           3.0  9.0   12.0  18.0
8      B           NaN  6.0    NaN  15.0
9two   A           NaN  2.0    NaN  11.0
10      B           5.0  8.0   14.0  17.0
通过传递 margins=True 来扩充此表以包含部分总计,将会添加ALL行和列标签,其中相应的值是单层中所有数据的分组统计值。
 1>>> df.pivot_table(index=["style","variable"] , columns="label" , values=["value1","value2"] , margins=True)
2               value1           value2
3label              No  Yes  All     No   Yes   All
4style variable
5one   A           4.0  NaN  4.0   13.0   NaN  13.0
6      B           NaN  4.0  4.0    NaN  13.0  13.0
7three A           3.0  9.0  6.0   12.0  18.0  15.0
8      B           NaN  6.0  6.0    NaN  15.0  15.0
9two   A           NaN  2.0  2.0    NaN  11.0  11.0
10      B           5.0  8.0  6.5   14.0  17.0  15.5
11All               4.0  5.8  5.0   13.0  14.8  14.0
该方法默认的聚合方法为均值mean,如果需要使用均值以外的聚合函数,请将其传递给 aggfunc 关键字参数。
 1>>> df.pivot_table(index=["style","variable"] , columns="label" , values=["value1","value2"] ,aggfunc=sum , margins=True)
2               value1           value2
3label              No   Yes All     No   Yes  All
4style variable
5one   A           8.0   NaN   8   26.0   NaN   26
6      B           NaN   4.0   4    NaN  13.0   13
7three A           3.0   9.0  12   12.0  18.0   30
8      B           NaN   6.0   6    NaN  15.0   15
9two   A           NaN   2.0   2    NaN  11.0   11
10      B           5.0   8.0  13   14.0  17.0   31
11All              16.0  29.0  45   52.0  74.0  126

在聚合情况下,可能会产生空值(或者NA),可以通过传递fill_value设置填充值。

 1>>> df.pivot_table(index=["style","variable"] , columns="label" , values=["value1","value2"] ,aggfunc=sum , margins=True , fill_value=99)
2               value1         value2
3label              No Yes All     No Yes  All
4style variable
5one   A             8  99   8     26  99   26
6      B            99   4   4     99  13   13
7three A             3   9  12     12  18   30
8      B            99   6   6     99  15   15
9two   A            99   2   2     99  11   11
10      B             5   8  13     14  17   31
11All                16  29  45     52  74  126

pivot_table参数选项如下所示:

参数选项名
说明
values 需要聚合的列名,默认情况下聚合所有数字列
index 在结果透视表的行上进行分组的列名或其他分组键
columns 在结果透视表的列上进行分组的列名或其他分组键
aggfunc 聚合函数或函数列表(默认情况下为mean),可以是groupby 上下文的任意有效函数
fill_value 替换结果表中的缺失值
dropna 如果为True,则不包含所有条目均为NA的列
margins 添加行/列小计和总计(默认为False 
margins_name 当传递margins=True时,用于设置边距行/列标签的名称;默认为“All”
observed 这仅适用于任何是分类的 groupers 。如果为True,仅显示分类分组的观察值。如果为 False显示分类分组的所有值


2.交叉表:
交叉表(cross-tabulation)(简称crosstab )是数据透视表的一个特例,计算的是分组频率。

首先构造一个示例DataFrame数据:

 1>>> df = pd.DataFrame({"style":["one""two""three","one""two""three","one""two""three"],
2...                    "variable":["A","A","A","B","B","B","A","B","A"],
3...                    "label":["No","Yes","No","Yes","No","Yes","No","Yes","Yes"],
4...                    "value1":np.arange(1,10),
5...                    "value2":np.arange(10,19)})
6
7>>> df
8   style variable label  value1  value2
90    one        A    No       1      10
101    two        A   Yes       2      11
112  three        A    No       3      12
123    one        B   Yes       4      13
134    two        B    No       5      14
145  three        B   Yes       6      15
156    one        A    No       7      16
167    two        B   Yes       8      17
178  three        A   Yes       9      18

假设,需要按照 style 列和 variable 列来总结数据,可以使用pivot_table 来实现这个功能,但是pandas.crosstab函数更为方便。

 1>>> df.pivot_table(index="style" , columns="variable" , values="value1" ,aggfunc="count" , margins=True)
2variable  A  B  All
3style
4one       2  1    3
5three     2  1    3
6two       1  2    3
7All       5  4    9
8
9
10>>> pd.crosstab(index=df["style"] , columns=df["variable"] , margins=True)
11variable  A  B  All
12style
13one       2  1    3
14three     2  1    3
15two       1  2    3
16All       5  4    9
crosstab 的前两个参数都可以是数组、Series 或数组列表。
 1>>> pd.crosstab(index=[df["style"],df["label"]] , columns=df["variable"] , margins=True)
2variable     A  B  All
3style label
4one   No     2  0    2
5      Yes    0  1    1
6three No     1  0    1
7      Yes    1  1    2
8two   No     0  1    1
9      Yes    1  1    2
10All          5  4    9
11
12
13>>> df.pivot_table(index=["style","label"] , columns="variable" , values="value1" ,aggfunc="count" , margins=True , fill_value=0)
14variable     A  B  All
15style label
16one   No     2  0    2
17      Yes    0  1    1
18three No     1  0    1
19      Yes    1  1    2
20two   No     0  1    1
21      Yes    1  1    2
22All          5  4    9


本篇文章来源于微信公众号: 码农设计师

RELATED ARTICLES

欢迎留下您的宝贵建议

Please enter your comment!
Please enter your name here

- Advertisment -

Most Popular

Recent Comments