在数据分析中,经常会遇到这样的情况:根据某一列(或多列)标签把数据划分为不同的组别,然后再对其进行数据分析。比如,某网站对注册用户的性别或者年龄等进行分组,从而研究出网站用户的画像(特点)。在 Pandas 中,要完成数据的分组操作,需要使用 groupby() 函数,它和 SQL 的GROUP BY操作非常相似。 

在划分出来的组(group)上应用一些统计函数,从而达到数据分析的目的,比如对分组数据进行聚合、转换,或者过滤。这个过程主要包含以下三步:

  • 拆分(Spliting):表示对数据进行分组;
  • 应用(Applying):对分组数据应用聚合函数,进行相应计算;
  • 合并(Combining):最后汇总计算结果。

下面对 groupby() 函数的应用过程进行具体的讲解。

创建DataFrame对象

首先我们创建一个 DataFrame 对象,下面数据描述了某班学生,计算机选修课的考试成绩:

  1. import pandas as pd
  2. import numpy as np
  3. data = {'Name': ['John', 'Helen', 'Sona', 'Ella'],
  4. 'score': [82, 98, 91, 87],
  5. 'option_course': ['C#','Python','Java','C']}
  6. df = pd.DataFrame(data)
  7. print(df)

输出结果:

    Name  score   option_course
0   John     82            C#
1  Helen     98        Python
2   Sona     91          Java
3   Ella     87             C

创建groupby分组对象

使用 groupby() 可以沿着任意轴分组。您可以把分组时指定的键(key)作为每组的组名,方法如下所示:

  • df.groupby("key")
  • df.groupby("key",axis=1)
  • df.groupby(["key1","key2"])

通过上述方法对 DataFrame 对象进行分组操作:

  1. import pandas as pd
  2. import numpy as np
  3. data = {'Name': ['John', 'Helen', 'Sona', 'Ella'],
  4. 'score': [82, 98, 91, 87],
  5. 'option_course': ['C#','Python','Java','C']}
  6. df = pd.DataFrame(data)
  7. print(df)
  8. #生成分组groupby对象
  9. print(df.groupby('score'))

输出结果:

<pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000021DE9A89640>

查看分组结果

1) groups查看分组结果

通过调用groups属性查看分组结果:

  1. import pandas as pd
  2. import numpy as np
  3. data = {'Name': ['John', 'Helen', 'Sona', 'Ella'],
  4. 'score': [82, 98, 91, 87],
  5. 'option_course': ['C#','Python','Java','C']}
  6. df = pd.DataFrame(data)
  7. #查看分组
  8. print(df.groupby('score').groups)

输出结果:

{82: Int64Index([0], dtype='int64'),
87: Int64Index([3], dtype='int64'),
91: Int64Index([2], dtype='int64'),
98: Int64Index([1], dtype='int64')}

2) 多个列标签分组

当然也可以指定多个列标签进行分组,示例如下:

  1. import pandas as pd
  2. import numpy as np
  3. data = {'Name': ['John', 'Helen', 'Sona', 'Ella'],
  4. 'score': [82, 98, 91, 87],
  5. 'option_course': ['C#','Python','Java','C']}
  6. df = pd.DataFrame(data)
  7. #查看分组
  8. print(df.groupby(['Name','score']).groups)

输出结果:

{('Ella', 87): Int64Index([3], dtype='int64'),
('Helen', 98): Int64Index([1], dtype='int64'),
('John', 82): Int64Index([0], dtype='int64'),
('Sona', 91): Int64Index([2], dtype='int64')}

通过 get_group() 方法可以选择组内的具体数据项:

  1. import pandas as pd
  2. import numpy as np
  3. data = {'Name': ['John', 'Helen', 'Sona', 'Ella'],
  4. 'score': [82, 98, 91, 87],
  5. 'option_course': ['C#','Python','Java','C']}
  6. df = pd.DataFrame(data)
  7. #根据score来分组
  8. grouped=df.groupby('score')
  9. #根据对应组的数据值,选择一个组
  10. print(grouped.get_group(91))

输出结果:

   Name  score option_course
2 Sona 91 Java

遍历分组数据

通过以下方法来遍历分组数据,示例如下:

  1. import pandas as pd
  2. import numpy as np
  3. data = {'Name': ['John', 'Helen', 'Sona', 'Ella'],
  4. 'score': [82, 98, 91, 87],
  5. 'option_course': ['C#','Python','Java','C']}
  6. df = pd.DataFrame(data)
  7. #查看分组
  8. grouped=df.groupby('score')
  9. for label, option_course in grouped:
  10. #其中key代表分组后字典的键,也就是score
  11. print(label)
  12. #字典对应的值选修的科目
  13. print(option_course)

输出结果:

82
Name score option_course
0 John 82 C#
87
Name score option_course
3 Ella 87 C
91
Name score option_course
2 Sona 91 Java
98
Name score option_course
1 Helen 98 Python

如上所示, groupby 对象的组名称与 score 中的的元素值一一对应。

应用聚合函数

当您在创建 groupby 对象时,通过 agg() 函数可以对分组对象应用多个聚合函数:

  1. import pandas as pd
  2. import numpy as np
  3. data = {'name': ['John', 'Helen', 'Sona', 'Ella'],
  4. 'score': [82, 98, 91, 87],
  5. 'option_course': ['C#','Python','Java','C']}
  6. df = pd.DataFrame(data)
  7. grouped=df.groupby('name')
  8. #应用一个聚合函数求均值
  9. print(grouped['score']).agg(np.mean)

输出结果:

name
Ella 87
Helen 98
John 82
Sona 91
Name: score, dtype: int64

当然,您也可以一次性应有多个聚合函数,示例如下:

  1. import pandas as pd
  2. import numpy as np
  3. data = {'name': ['John', 'Helen', 'Sona', 'Ella'],
  4. 'score': [82, 98, 91, 87],
  5. 'option_course': ['C#','Python','Java','C']}
  6. df = pd.DataFrame(data)
  7. grouped=df.groupby('name')
  8. print(grouped['score'].agg([np.size,np.mean,np.std]))

输出结果:

       size  mean  std
name
Ella 1 87 NaN
Helen 1 98 NaN
John 1 82 NaN
Sona 1 91 NaN

组的转换操作

在组的行或列上可以执行转换操作,最终会返回一个与组大小相同的索引对象。示例如下:

  1. import pandas as pd
  2. import numpy as np
  3. df = pd.DataFrame({'种类':['水果','水果','水果','蔬菜','蔬菜','肉类','肉类'],
  4. '产地':['朝鲜','中国','缅甸','中国','菲律宾','韩国','中国'],
  5. '水果':['橘子','苹果','哈密瓜','番茄','椰子','鱼肉','牛肉'],
  6. '数量':[3,5,5,3,2,15,9],
  7. '价格':[2,5,12,3,4,18,20]})
  8. #分组求均值,水果、蔬菜、肉类
  9. #对可执行计算的数值列求均值
  10. print(df.groupby('种类').transform(np.mean))
  11. #transform()直接应用demean,实现去均值操作
  12. demean = lambda arr:arr-arr.mean()
  13. print(df.groupby('种类').transform(demean))
  14. #自定义函数
  15. # 返回分组的前n行数据
  16. def get_rows(df,n):
  17. #从1到n行的所有列
  18. return df.iloc[:n,:]
  19. #分组后的组名作为行索引
  20. print(df.groupby('种类').apply(get_rows,n=1))

输出结果:

      数量         价格
0 4.333333 6.333333
1 4.333333 6.333333
2 4.333333 6.333333
3 2.500000 3.500000
4 2.500000 3.500000
5 12.000000 19.000000
6 12.000000 19.000000 数量 价格
0 -1.333333 -4.333333
1 0.666667 -1.333333
2 0.666667 5.666667
3 0.500000 -0.500000
4 -0.500000 0.500000
5 3.000000 -1.000000
6 -3.000000 1.000000 种类 产地 水果 数量 价格
种类
水果 0 水果 朝鲜 橘子 3 2
肉类 5 肉类 韩国 鱼肉 15 18
蔬菜 3 蔬菜 中国 番茄 3 3

组的数据过滤操作

通过 filter() 函数可以实现数据的筛选,该函数根据定义的条件过滤数据并返回一个新的数据集。

下面,筛选出参加比赛超过两次的球队(包含两次):

  1. import pandas as pd
  2. import numpy as np
  3. data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings',
  4. 'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'],
  5. 'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2],
  6. 'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017],
  7. 'Points':[874,789,863,663,741,802,756,788,694,701,812,698]}
  8. df = pd.DataFrame(data)
  9. #定义lambda函数来筛选数据
  10. print (df.groupby('Team').filter(lambda x: len(x) >= 2))

输出结果:

      Team  Rank  Year  Points
0 Riders 1 2014 874
1 Riders 2 2015 789
4 Kings 3 2014 741
6 Kings 1 2016 756
7 Kings 1 2017 788
8 Riders 2 2016 694
11 Riders 2 2017 698

pandas之分组操作的更多相关文章

  1. pandas groupby 分组操作

    最一般化的groupby 方法是apply. tips=pd.read_csv('tips.csv') tips[:5] 新生成一列 tips['tip_pct']=tips['tip']/tips[ ...

  2. 数据分析05 /pandas的高级操作

    数据分析05 /pandas的高级操作 目录 数据分析05 /pandas的高级操作 1. 替换操作 2. 映射操作 3. 运算工具 4. 映射索引 / 更改之前索引 5. 排序实现的随机抽样/打乱表 ...

  3. pandas的apply操作

    pandas的apply操作类似于Scala的udf一样方便,假设存在如下dataframe: id_part pred pred_class v_id 0 d [0.722817, 0.650064 ...

  4. Linq分组操作之GroupBy,GroupJoin扩展方法源码分析

    Linq分组操作之GroupBy,GroupJoin扩展方法源码分析 一. GroupBy 解释: 根据指定的键选择器函数对序列中的元素进行分组,并且从每个组及其键中创建结果值. 查询表达式: var ...

  5. MYSQL常用函数以及分组操作

    SELECT CONVERT(",SIGNED); SELECT CAST(" AS SIGNED); SELECT ; SELECT LENGTH("姜浩真帅!&quo ...

  6. HAVING 搜索条件在进行分组操作之后应用

    HAVING 搜索条件在进行分组操作之后应用: 如:查询帖子访问量大于15的用户id: select t.user_id,u.name,sum(count_view) from t_topic t l ...

  7. Pandas的基础操作(一)——矩阵表的创建及其属性

    Pandas的基础操作(一)——矩阵表的创建及其属性 (注:记得在文件开头导入import numpy as np以及import pandas as pd) import pandas as pd ...

  8. python数据结构:pandas(2)数据操作

    一.Pandas的数据操作 0.DataFrame的数据结构 1.Series索引操作 (0)Series class Series(base.IndexOpsMixin, generic.NDFra ...

  9. Pandas的拼接操作

    pandas的拼接操作 pandas的拼接分为两种: 级联:pd.concat, pd.append 合并:pd.merge, pd.join import pandas as pd import n ...

  10. Java对MongoDB进行分组操作并统计各个分组的数量

    最近在检索MongoDB的数据时需要用到分组操作,由于没有现成的说明文档可参考,只能是在代码中不断调试.摸索前进:目前已现实了Java对MongoDB的分组操作,并统计各个分组的数量.现通过示例详细解 ...

随机推荐

  1. Django框架搭建web项目(二)

    1.在路径XXXXX\mydjango\mydjango\mydjango下新建views.py(在浏览器中url请求后所展示的内容设置) from django.http import HttpRe ...

  2. Educational Codeforces Round 1 个人总结A-E

    Educational Codeforces Round 1 A. Tricky Sum 数学,求\(1 \dots n\)的和减去 小于等于n的二次幂乘2之和 LL f[40]; void solv ...

  3. 【python】第二模块 步骤一 第一课、MySQL的介绍

    第一课.MySQL的介绍 一.课程介绍 1.1 课程介绍 学习目标 了解关系型数据库的重要性 为什么会出现关系型数据库? 有哪些常见的关系型数据库? 掌握MySQL的安装和配置 怎么安装MySQL数据 ...

  4. Ubuntu系统update时提示源不安全被禁用的一种解决办法

    参考自这篇文章Ubuntu系统update时提示源不安全被禁用 - 知乎 (zhihu.com). 安装好Ubuntu18.04并更换清华源后,在运行 sudo apt update 更新源时报错如下 ...

  5. Activity基础知识

    Activity 一.Activity是什么 Activity是一种可以包含用户界面的组件,主要用于和用户进行交互.一个应用程序可以包含零个或多个活动. 二.活动的基本用法 1. 手动创建活动 ​ 打 ...

  6. 20193314白晨阳《Python程序设计》实验四 Python综合实践

    课程:<Python程序设计> 班级: 1933 姓名: 白晨阳 学号:20193314 实验教师:王志强老师 实验日期:2021年6月13日 必修/选修: 公选课 实验内容: Pytho ...

  7. Using Semaphores in Delphi, Part 2: The Connection Pool

    Abstract: Semaphores are used to coordinate multiple threads and processes. That semaphores provide ...

  8. LNMP架构的演变

    LNMP 演变 工作原理 linux + nginx + mariadb + php 工作原理: 首先,浏览器发送http request请求到服务器(Nginx),服务器响应并处理web请求, 将一 ...

  9. shell命令查找文件

    1.find命令的参数下面是find命令一些常用参数的例子,有用到的时候查查就行了,像上面前几个贴子,都用到了其中的的一些参数,也可以用man或查看论坛里其它贴子有find命令手册使用name选项文件 ...

  10. @DeclareParents声明对象的AOP

    今天在使用@DeclareParents时,使用AspectJ拓展对象的接口 public interface Encoreable { void nextPerformance(); } @Comp ...