pandas group分组与agg聚合的实例
作者:xusworld 发布时间:2023-01-04 14:22:28
如下:
import pandas as pd
df = pd.DataFrame({'Country':['China','China', 'India', 'India', 'America', 'Japan', 'China', 'India'],
'Income':[10000, 10000, 5000, 5002, 40000, 50000, 8000, 5000],
'Age':[5000, 4321, 1234, 4010, 250, 250, 4500, 4321]})
构造的数据如下:
Age Country Income
0 5000 China 10000
1 4321 China 10000
2 1234 India 5000
3 4010 India 5002
4 250 America 40000
5 250 Japan 50000
6 4500 China 8000
7 4321 India 5000
分组
单列分组
df_gb = df.groupby('Country')
for index, data in df_gb:
print(index)
print(data)
输出
America
Age Country Income
4 250 America 40000
China
Age Country Income
0 5000 China 10000
1 4321 China 10000
6 4500 China 8000
India
Age Country Income
2 1234 India 5000
3 4010 India 5002
7 4321 India 5000
Japan
Age Country Income
5 250 Japan 50000
多列分组
df_gb = df.groupby(['Country', 'Income'])
for (index1, index2), data in df_gb:
print((index1, index2))
print(data)
输出
('America', 40000)
Age Country Income
4 250 America 40000
('China', 8000)
Age Country Income
6 4500 China 8000
('China', 10000)
Age Country Income
0 5000 China 10000
1 4321 China 10000
('India', 5000)
Age Country Income
2 1234 India 5000
7 4321 India 5000
('India', 5002)
Age Country Income
3 4010 India 5002
('Japan', 50000)
Age Country Income
5 250 Japan 50000
聚合
对分组后数据进行聚合
默认情况对分组之后其他列进行聚合
df_agg = df.groupby('Country').agg(['min', 'mean', 'max'])
print(df_agg)
输出
Age Income
min mean max min mean max
Country
America 250 250.000000 250 40000 40000.000000 40000
China 4321 4607.000000 5000 8000 9333.333333 10000
India 1234 3188.333333 4321 5000 5000.666667 5002
Japan 250 250.000000 250 50000 50000.000000 50000
对分组后的部分列进行聚合
某些情况,只需要对部分数据进行不同的聚合操作,可以通过字典来构建
num_agg = {'Age':['min', 'mean', 'max']}
print(df.groupby('Country').agg(num_agg))
输出
Age
min mean max
Country
America 250 250.000000 250
China 4321 4607.000000 5000
India 1234 3188.333333 4321
Japan 250 250.000000 250
num_agg = {'Age':['min', 'mean', 'max'], 'Income':['min', 'max']}
print(df.groupby('Country').agg(num_agg))
输出
Age Income
min mean max min max
Country
America 250 250.000000 250 40000 40000
China 4321 4607.000000 5000 8000 10000
India 1234 3188.333333 4321 5000 5002
Japan 250 250.000000 250 50000 50000
补充:pandas——很全的groupby、agg,对表格数据分组与统计
我这篇groupby写的不好。太复杂了。其实实际上经常用的就那么几个。举个例子,把常用的往那一放就很容易理解和拿来用了。日后再写一篇。
groupby功能:分组
groupby + agg(聚集函数们): 分组后,对各组应用一些函数,如'sum',‘mean',‘max',‘min'…
groupby默认纵方向上分组,axis=0
DataFrame
import pandas as pd
import numpy as np
df = pd.DataFrame({'key1':['a', 'a', 'b', 'b', 'a'],
'key2':['one', 'two', 'one', 'two', 'one'],
'data1':np.random.randn(5),
'data2':np.random.randn(5)})
print(df)
data1 data2 key1 key2
0 -0.410122 0.247895 a one
1 -0.627470 -0.989268 a two
2 0.179488 -0.054570 b one
3 -0.299878 -1.640494 b two
4 -0.297191 0.954447 a one
分组,并对分组进行迭代
list(df.groupby(['key1']))#list后得到:[(group1),(group2),......]
[('a', data1 data2 key1 key2
0 -0.410122 0.247895 a one
1 -0.627470 -0.989268 a two
4 -0.297191 0.954447 a one), ('b', data1 data2 key1 key2
2 0.179488 -0.054570 b one
3 -0.299878 -1.640494 b two)]
list后得到:[(group1),(group2),…]
每个数据片(group)格式: (name,group)元组
1. 按key1(一个列)分组,其实是按key1的值
groupby对象支持迭代,产生一组二元元组:(分组名,数据块),(分组名,数据块)…
for name,group in df.groupby(['key1']):
print(name)
print(group)
a
data1 data2 key1 key2
0 -0.410122 0.247895 a one
1 -0.627470 -0.989268 a two
4 -0.297191 0.954447 a one
b
data1 data2 key1 key2
2 0.179488 -0.054570 b one
3 -0.299878 -1.640494 b two
2. 按[key1, key2](多个列)分组
对于多重键,产生的一组二元元组:((k1,k2),数据块),((k1,k2),数据块)…
第一个元素是由键值组成的元组
for name,group in df.groupby(['key1','key2']):
print(name) #name=(k1,k2)
print(group)
('a', 'one')
data1 data2 key1 key2
0 -0.410122 0.247895 a one
4 -0.297191 0.954447 a one
('a', 'two')
data1 data2 key1 key2
1 -0.62747 -0.989268 a two
('b', 'one')
data1 data2 key1 key2
2 0.179488 -0.05457 b one
('b', 'two')
data1 data2 key1 key2
3 -0.299878 -1.640494 b two
3. 按函数分组
4. 按字典分组
5. 按索引级别分组
6.将函数跟数组、列表、字典、Series混合使用也不是问题,因为任何东西最终都会被转换为数组
将这些数据片段做成字典
dict(list(df.groupby(['key1'])))#dict(list())
{'a': data1 data2 key1 key2
0 -0.410122 0.247895 a one
1 -0.627470 -0.989268 a two
4 -0.297191 0.954447 a one, 'b': data1 data2 key1 key2
2 0.179488 -0.054570 b one
3 -0.299878 -1.640494 b two}
分组后进行一些统计、计算等
1. 分组后,返回一个含有分组大小的Series
按key1分组
df.groupby(['key1']).size()
key1
a 3
b 2
dtype: int64
dict(['a1','x2','e3'])
{'a': '1', 'e': '3', 'x': '2'}
按[key1,key2]分组
df.groupby(['key1','key2']).size()
key1 key2
a one 2
two 1
b one 1
two 1
dtype: int64
2. 对data1按key1进行分组,并计算data1列的平均值
df['data1'].groupby(df['key1']).mean()
#groupby没有进行任何的计算。它只是进行了一个分组
key1
a -0.444928
b -0.060195
Name: data1, dtype: float64
df.groupby(['key1'])['data1'].mean()#理解:对df按key1分组,并计算分组后df['data1']的均值
#等价于:df.groupby(['key1']).data1.mean()
key1
a -0.444928
b -0.060195
Name: data1, dtype: float64
说明:
groupby没有进行任何的计算。它只是进行了一个分组。
数据(Series)根据分组键进行了聚合,产生了一个新的Series,其索引为key1列中的唯一值。
这种索引操作所返回的对象是一个已分组的DataFrame(如果传入的是列表或数组)或已分组的Series
df.groupby(['key1'])['data1'].size()
key1
a 3
b 2
Name: data1, dtype: int64
3.对data1按[key1,key2]进行分组,并计算data1的平均值
df['data1'].groupby([df['key1'],df['key2']]).mean()
key1 key2
a one -0.353657
two -0.627470
b one 0.179488
two -0.299878
Name: data1, dtype: float64
df.groupby(['key1','key2'])['data1'].mean()
#等价于:df.groupby(['key1','key2']).data1'.mean()
key1 key2
a one -0.353657
two -0.627470
b one 0.179488
two -0.299878
Name: data1, dtype: float64
通过两个键对数据进行了分组,得到的Series具有一个层次化索引(由唯一的键对组成):
df.groupby(['key1','key2'])['data1'].mean().unstack()
key2 | one | two |
---|---|---|
key1 | ||
a | -0.353657 | -0.627470 |
b | 0.179488 | -0.299878 |
在上面这些示例中,分组键均为Series。实际上,分组键可以是任何长度适当的数组。非常灵活。
横方向上
按列的数据类型(df.dtypes)来分
df共两种数据类型:float64和object,所以会分为两组(dtype(‘float64'),数据片),(dtype(‘O'), 数据片)
list(df.groupby(df.dtypes, axis=1))
[(dtype('float64'), data1 data2
0 -0.410122 0.247895
1 -0.627470 -0.989268
2 0.179488 -0.054570
3 -0.299878 -1.640494
4 -0.297191 0.954447), (dtype('O'), key1 key2
0 a one
1 a two
2 b one
3 b two
4 a one)]
agg的应用
groupby+agg 可以对groupby的结果同时应用多个函数
SeriesGroupBy的方法agg()参数:
aggregate(self, func_or_funcs, * args, ** kwargs)
func: function, string, dictionary, or list of string/functions
返回:aggregated的Series
s= pd.Series([10,20,30,40])
s
0 10
1 20
2 30
3 40
dtype: int64
for n,g in s.groupby([1,1,2,2]):
print(n)
print(g)
0 10
1 20
dtype: int64
2
2 30
3 40
dtype: int64
s.groupby([1,1,2,2]).min()
1
1 10
2 30
dtype: int64
#等价于这个:
s.groupby([1,1,2,2]).agg('min')
1 10
2 30
dtype: int64
s.groupby([1,1,2,2]).agg(['min','max'])#加[],func仅接受一个参数
min | max | |
---|---|---|
1 | 10 | 20 |
2 | 30 | 40 |
常常这样用:
df
data1 | data2 | key1 | key2 | |
---|---|---|---|---|
0 | -0.410122 | 0.247895 | a | one |
1 | -0.627470 | -0.989268 | a | two |
2 | 0.179488 | -0.054570 | b | one |
3 | -0.299878 | -1.640494 | b | two |
4 | -0.297191 | 0.954447 | a | one |
比较下面,可以看出agg的用处:
df.groupby(['key1'])['data1'].min()
key1
a -0.627470
b -0.299878
Name: data1, dtype: float64
df.groupby(['key1'])['data1'].agg({'min'})
min | |
---|---|
key1 | |
a | -0.627470 |
b | -0.299878 |
#推荐用这个√
df.groupby(['key1']).agg({'data1':'min'})#对data1列,取各组的最小值,名字还是data1
data1 | |
---|---|
key1 | |
a | -0.627470 |
b | -0.299878 |
#按key1分组后,aggregate各组data1的最小值和最大值:
df.groupby(['key1'])['data1'].agg({'min','max'})
max | min | |
---|---|---|
key1 | ||
a | -0.297191 | -0.627470 |
b | 0.179488 | -0.299878 |
#推荐用这个√
df.groupby(['key1']).agg({'data1':['min','max']})
data1 | ||
---|---|---|
min | max | |
key1 | ||
a | -0.627470 | -0.297191 |
b | -0.299878 | 0.179488 |
可以对groupby的结果更正列名(不推荐用这个,哪怕在后面单独更改列名)
# 对data1,把min更名为a,max更名为b
df.groupby(['key1'])['data1'].agg({'a':'min','b':'max'})#这里的'min' 'max'为两个函数名
d:\python27\lib\site-packages\ipykernel_launcher.py:2: FutureWarning: using a dict on a Series for aggregation
is deprecated and will be removed in a future version
a | b | |
---|---|---|
key1 | ||
a | -0.627470 | -0.297191 |
b | -0.299878 | 0.179488 |
重要技巧: groupby之后直接.reset_index()可以得到一个没有多级索引的DataFrame
之后可以通过df.rename({‘old_col1':‘new_col1',‘old_col2':‘new_col2',…})重命名
eg:
df1= df.groupby(['date'])['price'].agg({'sum','count'}).reset_index()
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。
来源:https://blog.csdn.net/u012706792/article/details/80892510
猜你喜欢
- 1 新建类库MyTestDLL2 右击项目“MyTestDLL”-》属性-》生成-》勾选“为COM互操作注册”3 打开 AssemblyIn
- 本文给大家介绍PHP中Http协议post请求参数,具体内容如下所示:WEB开发中信息基本全是在POST与GET请求与响应中进行,GET因其
- 很有趣的招聘方式和题目:以下是该次招聘前端开发工程师的聘题解答:小贤是一条可爱的小狗(Dog),它的叫声很好听(wow),每次看到主人的时候
- 前言工作中使用了redux-saga这个redux中间件,如果不明白内部原理使用起来会让人摸不着头脑,阅读源码后特意对其原理做下总结。red
- 首先要注册一个账号密码,通过账号密码登录,并且滑块验证,自动输入搜索关键词,进行跳转翻页爬取数据,并保存到Excel文件中。代码运行时,滑块
- 给浏览器绑定事件有时候是非常痛苦的事情,不同的浏览器提供不尽相同的功能的同时,也提供了不同的事件。例如,IE 系列的浏览器支持 mousee
- 数据可视化的时候,常常需要将多个子图放在同一个画板上进行比较,python 的matplotlib包下的subplot可以帮助完成子功能。p
- 很早就在这里看到过解决方案,与嗷嗷讨论后发现这个方案还是很可靠的。当然,唯一的缺点就是每一个属性都要去Hack,但我在很多实践中,只用‘修正
- 修复Access数据库,我们一般使用微软Office 97中带的Access 97对数据库进行修复和整理。Access数据库被损坏分以下几种
- 一. 字符串生活中我们经常坐大巴车,每个座位一个编号,一个位置对应一个下标。 字符串中也有下标,要取出字符串中的部分数据,可以用下标取。py
- 测试的php文件 <?php $link=mysql_connect('localhost','root
- 一图胜“十”言:SQL Server 数据库总结 一个大概的总结 经过一段时间的学习,也对数据库有了一些认识。 数据库基本是由表,关系,操作
- 引言上一篇文章中引入了消息队列对秒杀流量做削峰的处理,我们使用的是Kafka,看起来似乎工作的不错,但其实还是有很多隐患存在,如果这些隐患不
- 一、创建一个进程要创建一个进程,最简单的方式是用一个目标函数实例化一个Process对象,然后与threading一样调用start()函数
- 先思考一些问题:它是做什么的、以及怎么使用它。带着这些问题往下走。consul是做什么的consul用于微服务下的服务治理。服务治理是什么?
- 线性回归是一种常见的机器学习算法,也是人工智能中常用的算法。它是一种用于预测数值型输出变量与一个或多个自变量之间线性关系的方法。例如,你可以
- 客户端: <%@ Page Language="C#" AutoEventWireup="true&qu
- 给静态网页加密的方法有很多,有的简单有的复杂。前两天看见有人问静态网页加密问题,就写了这个代码思路:加密时:先把用户的密钥A用md5加密为B
- <%'asp事务处理。'测试数据库为sql server,服务器为本机,数据库名为test,表名为a,两个字段id(i
- 今天给大家讲的是ASP给图片加水印的知识ASP给图片加水印是需要组件的…常用的有aspjpeg和中国人自己开发的wsImage…前者有30天