https://github.com/yeayee/joyful-pandas/blob/master/第3章%20分组.ipynb
1.根据某一列分组
经过groupby后会生成一个groupby对象,该对象本身不会返回任何东西,只有当相应的方法被调用才会起作用¶
grouped_single = df.groupby('School')
grouped_single.get_group('S_1')
2.根据某几列分组
grouped_mul = df.groupby(['School','Class'])
grouped_mul.get_group(('S_2','C_4'))
3.组容量与组数
grouped_single.size()
#返回每组的个数
grouped_mul.size()
grouped_single.ngroups
#返回组数
grouped_mul.ngroups
4.组的遍历
for name,group in grouped_single:
print(name)
display(group.head())
S_1
School Class Gender Address Height Weight Math Physics
ID
1101 S_1 C_1 M street_1 173 63 34.0 A+
1102 S_1 C_1 F street_2 192 73 32.5 B+
1103 S_1 C_1 M street_2 186 82 87.2 B+
1104 S_1 C_1 F street_2 167 81 80.4 B-
1105 S_1 C_1 F street_4 159 64 84.8 B+
S_2
School Class Gender Address Height Weight Math Physics
ID
2101 S_2 C_1 M street_7 174 84 83.3 C
2102 S_2 C_1 F street_6 161 61 50.6 B+
2103 S_2 C_1 M street_4 157 61 52.5 B-
2104 S_2 C_1 F street_5 159 97 72.2 B+
2105 S_2 C_1 M street_4 170 81 34.2 A
5.level参数(用于多级索引)和axis参数
6.其他
对分组对象使用head函数,返回的是每个组的前几行,而不是数据集前几行¶
first显示的是以分组为索引的每组的第一个分组信息
对于groupby函数而言,分组的依据是非常自由的,只要是与数据框长度相同的列表即可,同时支持函数型分组¶
df[:5].groupby(lambda x:print(x)).head(0)
根据奇偶行分组¶
df.groupby(lambda x:'奇数行' if not df.index.get_loc(x)%2==1 else '偶数行')
#df.index.get_loc返回x在df中的整数位置
如果是多层索引,那么lambda表达式中的输入就是元组,下面实现的功能为查看两所学校中男女生分别均分是否及格¶
math_score = df.set_index(['Gender','School'])['Math'].sort_index()
grouped_score = df.set_index(['Gender','School']).sort_index().\
groupby(lambda x:(x,'均分及格' if math_score[x].mean()>=60 else '均分不及格'))
for name,_ in grouped_score:print(name)
(('F', 'S_1'), '均分及格')
(('F', 'S_2'), '均分及格')
(('M', 'S_1'), '均分及格')
(('M', 'S_2'), '均分不及格')
7.groupby的[]操作:
可以用[]选出groupby对象的某个或者某几个列,上面的均分比较可以如下简洁地写出:¶
df.groupby(['Gender','School'])['Math'].mean()>=60
Out[18]:
Gender School
F S_1 True
S_2 True
M S_1 True
S_2 False
Name: Math, dtype: bool
用列表可选出多个属性列(统计表)
df.groupby([‘Gender’,‘School’])[[‘Math’,‘Height’]].mean()
8.连续型变量分组
例如利用cut函数对数学成绩分组
In [20]:
bins = [0,40,60,80,90,100]
cuts = pd.cut(df['Math'],bins=bins) #可选label添加自定义标签
df.groupby(cuts)['Math'].count()
Out[20]:
Math
(0, 40] 7
(40, 60] 10
(60, 80] 9
(80, 90] 7
(90, 100] 2