2.5. 分组汇总#
实际的数据分析中,经常需要对某一类数据进行统计分析。比如,假如我们拥有全国所有人的身高和体重数据,我们想按照省份分组,统计每个省的平均身高和平均体重,这时候就需要使用分组操作。pandas 提供了 groupby
函数进行类似的分组汇总操作。图 2.7 计算平均身高的分组汇总流程,主要包括两部分:分组与汇总。其中分组阶段将同一类的内容归结到相同的组中;汇总阶段将所关心的数据进行计算,比如求和、求平均等。
按哪些字段进行分组,这些字段又被成为 ** 分组变量 **。对其他字段进行汇总,其他汇总字段被成为 ** 汇总变量 **。对汇总变量进行计算,被称为 ** 汇总统计量 **。
Show code cell content
import os
import urllib.request
import zipfile
import pandas as pd
folder_path = os.path.join(os.getcwd(), "../data/pwt")
download_url = "https://www.rug.nl/ggdc/docs/pwt70_06032011version.zip"
file_name = download_url.split("/")[-1]
zip_file_path = os.path.join(folder_path, file_name)
if not os.path.exists(folder_path):
os.makedirs(folder_path)
if not os.path.exists(zip_file_path):
urllib.request.urlretrieve(download_url, zip_file_path)
with zipfile.ZipFile(zip_file_path, 'r') as zip_ref:
zip_ref.extractall(folder_path)
df = pd.read_csv(os.path.join(folder_path, "pwt70_w_country_names.csv"))
df = df.fillna(0)
文件夹已存在,无需操作。
分组变量#
在进行分组汇总时,分组变量可以有一个或多个。
例如,按照 country
和 year
分组,并对 tcgdp
汇总求平均值,此时在 groupby
后接多个分组变量,以列表形式写出。或者是 .groupby(by=['country','year'])
。.groupby
之后要接上所需要汇总的字段,这个例子是 tcgdp
。最后要接上所需要进行的汇总计算,比如 .mean()
。计算结果中产生了多个索引,本例中是 country
和 year
,指代相应组的情况。
df.groupby(['country','year'])[['tcgdp']].mean()
tcgdp | ||
---|---|---|
country | year | |
Afghanistan | 1950 | 0.000000 |
1951 | 0.000000 | |
1952 | 0.000000 | |
1953 | 0.000000 | |
1954 | 0.000000 | |
... | ... | ... |
Zimbabwe | 2005 | 1968.205961 |
2006 | 2132.305773 | |
2007 | 2107.937100 | |
2008 | 1772.209867 | |
2009 | 1906.049843 |
11400 rows × 1 columns
汇总变量#
在进行分组汇总时,汇总变量也可以有一个或多个。
例如按照 year
汇总 tcgdp
和 POP
,在 .groupby
后直接使用 []
筛选相应列,再接汇总统计量。
df.groupby(['year'])[['tcgdp','POP']].mean()
tcgdp | POP | |
---|---|---|
year | ||
1950 | 3954.394467 | 16239.392063 |
1951 | 4541.917011 | 16461.731179 |
1952 | 5150.946930 | 16730.487389 |
1953 | 5483.995310 | 17019.548668 |
1954 | 5692.811775 | 17326.304137 |
1955 | 6196.465477 | 17657.801874 |
1956 | 6640.264851 | 17999.434226 |
1957 | 7104.041128 | 18364.700442 |
1958 | 7528.454605 | 18730.439042 |
1959 | 8148.510891 | 19043.260395 |
1960 | 8828.605776 | 19242.437274 |
1961 | 9128.455879 | 19423.141142 |
1962 | 9687.307082 | 19760.533626 |
1963 | 10351.917775 | 20233.695226 |
1964 | 11269.680061 | 20719.860558 |
1965 | 12105.691273 | 21182.282832 |
1966 | 13176.722813 | 21655.463121 |
1967 | 14051.084235 | 22121.536947 |
1968 | 15421.584740 | 22606.150837 |
1969 | 17218.758987 | 23113.133937 |
1970 | 21282.567279 | 23618.829389 |
1971 | 23432.910689 | 24137.869711 |
1972 | 25833.379310 | 24644.483005 |
1973 | 29159.646600 | 25140.115900 |
1974 | 32601.678050 | 25623.884663 |
1975 | 36109.970163 | 26088.471411 |
1976 | 40165.947722 | 26535.470116 |
1977 | 44691.033777 | 26979.055474 |
1978 | 50393.152251 | 27418.046916 |
1979 | 56983.540963 | 27873.890479 |
1980 | 63850.748602 | 28329.849105 |
1981 | 70997.231877 | 28790.876000 |
1982 | 75786.116966 | 29287.531784 |
1983 | 81059.066064 | 29795.689879 |
1984 | 88303.031984 | 30288.007526 |
1985 | 94477.342887 | 30791.765868 |
1986 | 101596.414215 | 31313.561847 |
1987 | 109494.183517 | 31863.784021 |
1988 | 118048.078421 | 32417.290021 |
1989 | 126221.579493 | 32964.028537 |
1990 | 144220.075333 | 33516.168453 |
1991 | 151894.234358 | 34055.531837 |
1992 | 159301.705863 | 34567.649100 |
1993 | 168690.980704 | 35065.424347 |
1994 | 178947.613269 | 35548.469784 |
1995 | 190126.580304 | 36030.590795 |
1996 | 200132.766116 | 36513.694642 |
1997 | 210946.889843 | 36991.605037 |
1998 | 216481.948520 | 37462.231458 |
1999 | 228114.840291 | 37920.696968 |
2000 | 244206.601784 | 38307.409353 |
2001 | 255312.487062 | 38742.535742 |
2002 | 269661.409286 | 39176.028268 |
2003 | 286959.704885 | 39606.837547 |
2004 | 312186.334350 | 40040.118863 |
2005 | 344724.420195 | 40475.047642 |
2006 | 379205.674317 | 40909.750389 |
2007 | 416504.775669 | 41347.240695 |
2008 | 446441.988262 | 41731.031032 |
2009 | 448186.871127 | 42174.566563 |
汇总统计量#
groupby
后可接的汇总统计量有:
mean - 均值
max - 最大值
min - 最小值
median - 中位数
std - 标准差
mad - 平均绝对偏差
count - 计数
skew - 偏度
quantile - 指定分位数
这些统计量可以直接接 groupby 对象使用,此外,agg
方法提供了一次汇总多个统计量的方法。
例如,汇总各个国家 country
人口 POP
的均值、最大值、最小值。
df.groupby(['country'])['POP'].agg(['mean','min','max'])
mean | min | max | |
---|---|---|---|
country | |||
Afghanistan | 15707.344917 | 8150.368 | 31889.923 |
Albania | 2461.208000 | 1227.156 | 3250.778 |
Algeria | 19896.967967 | 8892.718 | 34178.000 |
Angola | 7295.199200 | 4117.617 | 12799.000 |
Antigua and Barbuda | 65.352367 | 45.816 | 85.700 |
... | ... | ... | ... |
Venezuela | 15180.664233 | 5009.006 | 27191.090 |
Vietnam | 54711.902183 | 25348.144 | 88577.000 |
Yemen | 10789.802917 | 4777.089 | 22858.000 |
Zambia | 6448.586433 | 2553.000 | 13061.000 |
Zimbabwe | 7567.034333 | 2853.151 | 11867.855 |
190 rows × 3 columns
多重索引#
在进行分组汇总操作时,产生的结果并不是常见的二维表数据框,而是具有多重索引的数据框。 pandas 开发者设计这种类型的数据框是借鉴了 Excel 数据透视表的功能。
例如,按照 country
和 year
顺序对 tcgdp
和 POP
进行分组汇总,汇总统计量为最小值和最大值。
df.groupby(['country','year'])[['tcgdp','POP']].agg(['min','max'])
tcgdp | POP | ||||
---|---|---|---|---|---|
min | max | min | max | ||
country | year | ||||
Afghanistan | 1950 | 0.000000 | 0.000000 | 8150.368 | 8150.368 |
1951 | 0.000000 | 0.000000 | 8284.473 | 8284.473 | |
1952 | 0.000000 | 0.000000 | 8425.333 | 8425.333 | |
1953 | 0.000000 | 0.000000 | 8573.217 | 8573.217 | |
1954 | 0.000000 | 0.000000 | 8728.408 | 8728.408 | |
... | ... | ... | ... | ... | ... |
Zimbabwe | 2005 | 1968.205961 | 1968.205961 | 11639.470 | 11639.470 |
2006 | 2132.305773 | 2132.305773 | 11544.326 | 11544.326 | |
2007 | 2107.937100 | 2107.937100 | 11443.187 | 11443.187 | |
2008 | 1772.209867 | 1772.209867 | 11350.000 | 11350.000 | |
2009 | 1906.049843 | 1906.049843 | 11383.000 | 11383.000 |
11400 rows × 4 columns
此时数据框中有两个行索引(country
和 year
)和两个列索引(tcgdp
+ POP
和 min
+ max
)。需要筛选列时,第一个 []
筛选第一重列索引(从 tcgdp
和 POP
中选择一个列),第二个 []
筛选第二重列索引(从 min
和 max
中选择一个列)。
例如,查询各个国家 country
各年 year
人口 POP
的最小值。
df_query = df.groupby(['country','year'])[['tcgdp','POP']].agg(['min','max'])
df_query['POP']['min']
country year
Afghanistan 1950 8150.368
1951 8284.473
1952 8425.333
1953 8573.217
1954 8728.408
...
Zimbabwe 2005 11639.470
2006 11544.326
2007 11443.187
2008 11350.000
2009 11383.000
Name: min, Length: 11400, dtype: float64