pandas分组groupby(agg,transform),apply

本文详细介绍了Pandas库中的分组操作,包括groupby函数的单/多列分组、聚合、过滤和变换,以及apply函数的灵活性和应用。通过实例展示了如何使用这些功能进行数据处理,如计算统计量、筛选组、进行组内变换等。
摘要由CSDN通过智能技术生成

pandas简单介绍和本文说明

pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具。pandas提供了大量能使我们快速便捷地处理数据的函数和方法。你很快就会发现,它是使Python成为强大而高效的数据分析环境的重要因素之一。
pandas is a fast, powerful, flexible and easy to use open source data analysis and manipulation tool,built on top of the Python programming language.

进入官网可以看到现在最新的版本是1.0.3,之后代码也就使用1.0.3的pd咯。此系列主要参考Pandas官方文档和由Datawhale主办的一期Joyful-Pandas,结合自己使用pandas的一些体会进行扩展,最后还有个人对问题和练习的解答。使用到的数据集可以在此下载
在这里插入图片描述

#从清华镜像拉装1.0.3版本的Pandas
!pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pandas==1.0.3
import pandas as pd
#查看Pandas版本
pd.__version__
'1.0.3'
df = pd.read_csv('work/table.csv',index_col='ID')
df.head()

一、SAC过程

SAC指的是分组操作中的split-apply-combine过程
在该过程中,我们实际往往会遇到四类问题:
整合(Aggregation)——即分组计算统计量(如求均值、求每组元素个数)
变换(Transformation)——即分组对每个单元的数据进行操作(如元素标准化)
过滤(Filtration)——即按照某些规则筛选出一些组(如选出组内某一指标小于50的组)
综合问题——即前面提及的三种问题的混合

二、groupby函数

1. groupby分组函数的基本内容

单/多列分组

经过groupby后会生成一个groupby对象,该对象本身不会返回任何东西,只有当相应的方法被调用才会起作用。

grouped_single = df.groupby('School')
print(grouped_single)
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x7f10981146d0>
print(grouped_single.get_group('S_1').head())

打印了School为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+
grouped_mul = df.groupby(['School','Class'])
grouped_mul.get_group(('S_2','C_4'))

根据多列分组

     School Class Gender   Address  Height  Weight  Math Physics
ID                                                              
2401    S_2   C_4      F  street_2     192      62  45.3       A
2402    S_2   C_4      M  street_7     166      82  48.7       B
2403    S_2   C_4      F  street_6     158      60  59.7      B+
2404    S_2   C_4      F  street_2     160      84  67.7       B
2405    S_2   C_4      F  street_6     193      54  47.6       B
组容量与组数
print('组容量与组数')
print(grouped_single.size())
print(grouped_mul.size())
print(grouped_single.ngroups)
print(grouped_mul.ngroups)
组容量与组数
School
S_1    15
S_2    20
dtype: int64
School  Class
S_1     C_1      5
        C_2      5
        C_3      5
S_2     C_1      5
        C_2      5
        C_3      5
        C_4      5
dtype: int64
2
7
组的遍历
for name,group in grouped_single:
    print(name)
    print(group)
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+
1201    S_1   C_2      M  street_5     188      68  97.0      A-
1202    S_1   C_2      F  street_4     176      94  63.5      B-
1203    S_1   C_2      M  street_6     160      53  58.8      A+
1204    S_1   C_2      F  street_5     162      63  33.8       B
1205    S_1   C_2      F  street_6     167      63  68.4      B-
1301    S_1   C_3      M  street_4     161      68  31.5      B+
1302    S_1   C_3      F  street_1     175      57  87.7      A-
1303    S_1   C_3      M  street_7     188      82  49.7       B
1304    S_1   C_3      M  street_2     195      70  85.2       A
1305    S_1   C_3      F  street_5     187      69  61.7      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
2201    S_2   C_2      M  street_5     193     100  39.1       B
2202    S_2   C_2      F  street_7     194      77  68.5      B+
2203    S_2   C_2      M  street_4     155      91  73.8      A+
2204    S_2   C_2      M  street_1     175      74  47.2      B-
2205    S_2   C_2      F  street_7     183      76  85.4       B
2301    S_2   C_3      F  street_4     157      78  72.3      B+
2302    S_2   C_3      M  street_5     171      88  32.7       A
2303    S_2   C_3      F  street_7     190      99  65.9       C
2304    S_2   C_3      F  street_6     164      81  95.5      A-
2305    S_2   C_3      M  street_4     187      73  48.9       B
2401    S_2   C_4      F  street_2     192      62  45.3       A
2402    S_2   C_4      M  street_7     166      82  48.7       B
2403    S_2   C_4      F  street_6     158      60  59.7      B+
2404    S_2   C_4      F  street_2     160      84  67.7       B
2405    S_2   C_4      F  street_6     193      54  47.6       B
level参数(用于多级索引)和axis参数

参数level,指明聚合的层级

print(df.set_index(['Gender','School']).groupby(level=1,axis=0).get_group('S_1').head()

level就是school,也可以直接用’school’——df.set_index(['Gender','School']).groupby(level='School',axis=0).get_group('S_1').head())

              Class   Address  Height  Weight  Math Physics
Gender School                                              
M      S_1      C_1  street_1     173      63  34.0      A+
F      S_1      C_1  street_2     192      73  32.5      B+
M      S_1      C_1  street_2     186      82  87.2      B+
F      S_1      C_1  street_2     167      81  80.4      B-
       S_1      C_1  street_4     159      64  84.8      B+

2.groupby对象的特点

print([attr for attr in dir(grouped_single) if not attr.startswith('_')])

[‘Address’, ‘Class’, ‘Gender’, ‘Height’, ‘Math’, ‘Physics’, ‘School’, ‘Weight’, ‘agg’, ‘aggregate’, ‘all’, ‘any’, ‘apply’, ‘backfill’, ‘bfill’, ‘boxplot’, ‘corr’, ‘corrwith’, ‘count’, ‘cov’, ‘cumcount’, ‘cummax’, ‘cummin’, ‘cumprod’, ‘cumsum’, ‘describe’, ‘diff’, ‘dtypes’, ‘expanding’, ‘ffill’, ‘fillna’, ‘filter’, ‘first’, ‘get_group’, ‘groups’, ‘head’, ‘hist’, ‘idxmax’, ‘idxmin’, ‘indices’, ‘last’, ‘mad’, ‘max’, ‘mean’, ‘median’, ‘min’, ‘ndim’, ‘ngroup’, ‘ngroups’, ‘nth’, ‘nunique’, ‘ohlc’, ‘pad’, ‘pct_change’, ‘pipe’, ‘plot’, ‘prod’, ‘quantile’, ‘rank’, ‘resample’, ‘rolling’, ‘sem’, ‘shift’, ‘size’, ‘skew’, ‘std’, ‘sum’, ‘tail’, ‘take’, ‘transform’, ‘tshift’, ‘var’]
groupby对象可以使用相当多的函数,灵活程度很高

分组对象的head和first

grouped_single.head(2)对分组对象使用head函数,返回的是每个组的前几行,而不是数据集前几行。
first显示的是以分组为索引的每组的第一个分组信息。grouped_single.first()

分组依据

对于groupby函数而言,分组的依据是非常自由的,只要是与数据框长度相同的列表即可,同时支持函数型分组。

df.groupby(np.random.choice(['a','b','c'],df.shape[0])).get_group('a').head()
#相当于将np.random.choice(['a','b','c'],df.shape[0])当做新的一列进行分组

从原理上说,我们可以看到利用函数时,传入的对象就是索引,因此根据这一特性可以做一些复杂的操作。比如根据奇偶行分组:

df.groupby(lambda x:'奇数行' if not df.index.get_loc(x)%2==1 else '偶数行').groups
{'偶数行': Int64Index([1102, 1104, 1201, 1203, 1205, 1302, 1304, 2101, 2103, 2105, 2202,
             2204, 2301, 2303, 2305, 2402, 2404],
            dtype='int64', name='ID'),
 '奇数行': Int64Index([1101, 1103, 1105, 1202, 1204, 1301, 1303, 1305, 2102, 2104, 2201,
             2203, 2205, 2302, 2304, 2401, 2403, 2405],
            dtype='int64', name='ID')}

m.groups() 返回所有括号匹配的字符,以tuple格式。
m.groups() == (m.group(0), m.group(1), …)
如果是多层索引,那么lambda表达式中的输入就是元组,下面实现的功能为查看两所学校中男女生分别均分是否及格。注意:此处只是演示groupby的用法,实际操作不会这样写。

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:
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值