【Pandas学习笔记Task04】:分组

import numpy as np
import pandas as pd

df = pd.read_csv('data/learn_pandas.csv')

一、分组模式及其对象

1.分组的一般模式

想要实现分组操作,需要明确三个要素:分组依据、数据来源、操作及其返回结果。
分组其实也就相当于在原来对整列的操作上,将列划分为几部分。就比如下面的根据性别统计身高。性别是依据,可以理解为将身高列中的数据,先根据性别化为两部分(性别只有俩值),然后分别操作就行了。

# 按照性别统计身高的中位数。
df.groupby('Gender')['Height'].median()
Gender
Female    159.6
Male      173.4
Name: Height, dtype: float64

2.分组依据的本质

对多个维度分组,只需要在groupby中传入一个列表就行。

item = np.random.choice(list('abc'), df.shape[0])
df.groupby(item)['Height'].mean()
a    163.571429
b    163.244444
c    162.962195
Name: Height, dtype: float64
# df.groupby(['School', 'Gender'])['Height'].mean()
df.groupby([df['School'], df['Gender']])['Height'].mean()
School                         Gender
Fudan University               Female    158.776923
                               Male      174.212500
Peking University              Female    158.666667
                               Male      172.030000
Shanghai Jiao Tong University  Female    159.122500
                               Male      176.760000
Tsinghua University            Female    159.753333
                               Male      171.638889
Name: Height, dtype: float64

3.Groupby对象

gb = df.groupby(['School','Gender'])
gb.ngroups # 得到分组个数
8
res = gb.groups # groups可以得到每个组以及其值的字典
res.keys()
dict_keys([('Fudan University', 'Female'), ('Fudan University', 'Male'), ('Peking University', 'Female'), ('Peking University', 'Male'), ('Shanghai Jiao Tong University', 'Female'), ('Shanghai Jiao Tong University', 'Male'), ('Tsinghua University', 'Female'), ('Tsinghua University', 'Male')])
gb.size() #返回的是每个组值的个数
School                         Gender
Fudan University               Female    30
                               Male      10
Peking University              Female    22
                               Male      12
Shanghai Jiao Tong University  Female    41
                               Male      16
Tsinghua University            Female    48
                               Male      21
dtype: int64
# 只能传列名
gb.get_group(('Fudan University', 'Female')).iloc[:3,:3]# 这里去掉了名字所在的列。(我理解相当于当做索引了)
SchoolGradeName
3Fudan UniversitySophomoreXiaojuan Sun
15Fudan UniversityFreshmanChangqiang Yang
26Fudan UniversityJuniorYanli You

二、聚合函数

1.内置聚合函数

2.agg方法

【a】使用多个函数
【b】对特定的列使用特定的聚合函数
【c】使用自定义函数

gb = df.groupby('Gender')[['Height','Weight']]
gb.agg(['mean', 'idxmax', 'skew']) # 多个函数直接传列表
gb.agg({'Height':['mean','max'],'Weight':'count'}) # 对特定列执行特定聚合函数的话传字典
gb.agg(lambda x: x.mean() - x.min()) # 自定义函数
#这里想到apply。apply针对的是未分组前的df,对整列求。这个agg是对分组后所在组的列分别求
HeightWeight
Gender
Female13.7969713.918519
Male17.9254921.759259
# 对聚合结果重命名
gb.agg([('range', lambda x: x.max() - x.min())]) # 将a传的列表中的函数名字改为自定义元组。
HeightWeight
rangerange
Gender
Female24.829.0
Male38.238.0

三、变换和过滤

1.变换函数与transform方法

gb.cummax().head()# 完成的是组内累积操作。与聚合函数类似
HeightWeight
0158.946.0
1166.570.0
2188.989.0
3NaN46.0
4188.989.0
# 自定义变换利用transform方法。
gb.transform(lambda x: (x-x.mean())/x.std()).head()
HeightWeight
0-0.058760-0.354888
1-1.010925-0.355000
22.1670632.089498
3NaN-1.279789
40.0531330.159631
gb.transform('mean').head() # 标量广播
# 构造两列新特征来分别表示样本所在性别组的身高均值和体重均值
# gb.agg('mean').head()
# 这里可以理解将聚合的值加到新的列中。
HeightWeight
0159.1969747.918519
1173.6254972.759259
2173.6254972.759259
3159.1969747.918519
4173.6254972.759259

2.组索引与过滤

之前的索引是对所有行进行筛选,而组过滤可以理解为是在一个组内对所有行进行筛选。

gb.filter(lambda x: x.shape[0] > 100).head()
HeightWeight
0158.946.0
3NaN41.0
5158.051.0
6162.552.0
7161.950.0
df[['Height','Weight']].shape
(200, 2)

四、跨列分组

1. apply的使用

# 对多列同时处理
gb.apply(lambda x: (x['Weight']/(x['Height']/100)**2).mean())
Gender
Female    18.860930
Male      24.318654
dtype: float64
gb = df.groupby(['Gender','Test_Number'])[['Height','Weight']]
gb.apply(lambda x: 0)
Gender  Test_Number
Female  1              0
        2              0
        3              0
Male    1              0
        2              0
        3              0
dtype: int64
gb.apply(lambda x: [0, 0]) # 这里列表仍然看作标量(emmm)。
Gender  Test_Number
Female  1              [0, 0]
        2              [0, 0]
        3              [0, 0]
Male    1              [0, 0]
        2              [0, 0]
        3              [0, 0]
dtype: object
gb.apply(lambda x: pd.Series([0,0],index=['a','b']))
ab
GenderTest_Number
Female100
200
300
Male100
200
300
gb.apply(lambda x: pd.DataFrame(np.ones((2,2)),
                                    index = ['a','b'],
                                    columns=pd.Index([('w','x'),('y','z')])))
wy
xz
GenderTest_Number
Female1a1.01.0
b1.01.0
2a1.01.0
b1.01.0
3a1.01.0
b1.01.0
Male1a1.01.0
b1.01.0
2a1.01.0
b1.01.0
3a1.01.0
b1.01.0

总结:本次学习尚有很多内容未理解透彻,还需继续补充。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值