pandas提供基于行和列的聚合操作,groupby可理解为是基于行的,agg则是基于列的
从实现上看,groupby返回的是一个DataFrameGroupBy结构,这个结构必须调用聚合函数(如sum)之后,才会得到结构为Series的数据结果。
而agg是DataFrame的直接方法,返回的也是一个DataFrame。当然,很多功能用sum、mean等等也可以实现。但是agg更加简洁, 而且传给它的函数可以是字符串,也可以自定义,参数是column对应的子DataFrame
一、pandas.group_by
首先来看一下案例的数据格式,使用head函数调用DataFrame的前8条记录,这里一共4个属性
column_map.head(8)
work_order work_station range_low range_high
1 0 2 1 12
2 0 2 13 24
3 0 2 25 36
4 0 2 37 48
5 0 2 49 60
6 0 2 61 72
7 0 2 73 84
8 0 2 85 96
work_order 表示工序, work_station表示工位,rang_low, range_high 表示对应记录的上下限,现在使用groupby统计每个工序工位下面各有多少条记录
column_map.groupby(['work_order','work_station'])
我们会发现输出的是一个GroupBy类,并非我们想要的结果
<pandas.core.groupby.DataFrameGroupBy object at 0x111242630>
还需要加上一个聚合函数,比如
wo_ws_group = column_map.groupby(['work_order','work_station'])
wo_ws_group.size()
我们就可以得到
work_order work_station
0 11 216
2 61
3 3
4 398
1 1 94
10 222
11 232
16 871
17 81
3 41
5 55
6 17
8 11
3 1 201
dtype: int64
新出现的列对应着每个工序工位下面有多少条记录
但是我们可以发现它的格式已经和我们平时使用的DataFrame不太一样了,我们可以使用下面的命令解决
wo_ws_group.size().reset_index()
work_order work_station 0
0 0 11 216
1 0 2 61
2 0 3 3
3 0 4 398
4 1 1 94
5 1 10 222
6 1 11 232
7 1 16 871
8 1 17 81
9 1 3 41
10 1 5 55
11 1 6 17
12 1 8 11
13 3 1 201
想要查询具体每一个记录,可以使用loc命令
wo_ws_group.size().loc['0','11']
216
使用get_group可以查询具体每一个分组下面的所有记录
wo_ws_group.get_group(('0','11'))
因为比较多就显示全部了,使用head,显示前几条记录
wo_ws_group.get_group(('0','11')).head(8)
work_order work_station range_low range_high
463 0 11 5545 5556
464 0 11 5557 5568
465 0 11 5569 5580
466 0 11 5581 5592
467 0 11 5593 5604
468 0 11 5605 5616
469 0 11 5617 5628
470 0 11 5629 5640
我们还可以使用idxmin(),idxmax()函数,获得每一个分组下面所有记录中数值最大最小的index
wo_ws_group['range_low'].idxmin()
work_order work_station
0 11 463
2 1
3 62
4 85
1 1 1257
10 835
11 1025
16 1552
17 2423
3 679
5 720
6 775
8 792
3 1 1351
Name: range_low, dtype: int64
wo_ws_group['range_high'].idxmax()
work_order work_station
0 11 678
2 8
3 64
4 83
1 1 1350
10 833
11 1256
16 2422
17 2503
3 719
5 774
6 791
8 802
3 1 1551
Name: range_high, dtype: int64
对于分组结果的每一列还可以使用apply,进行一些函数的二次处理,如
wo_ws_group['work_order'].apply(lambda x:2*x).head(8)
1 00
2 00
3 00
4 00
5 00
6 00
7 00
8 00
Name: work_order, dtype: object
由于这里的0是字符串类型,所以2*以后都变成了2个0
二、pandas.agg
agg的使用比groupby还要简介一些,我们现自己创建一个DataFrame作为例子
data = pd.DataFrame([[2,11],[1,23],[5,11],[1.3,44],[5,111]],columns = ['price','quantity'],dtype = float)
price quantity
0 2.0 11.0
1 1.0 23.0
2 5.0 11.0
3 1.3 44.0
4 5.0 111.0
使用agg统计每一列的求和与平均值
data[['price','quantity']].agg(['sum','mean'])
price quantity
sum 14.30 200.0
mean 2.86 40.0
还支持对每一列不同的操作
data.agg({'price':['sum','mean'],'quantity':['sum']})
price quantity
mean 2.86 NaN
sum 14.30 200.0
如果需要自定义一些函数的 话可以使用lambda函数
get_max = lambda x:x.sort_values(ascending = False).iloc[0]
get_max.__name__ = "get_max"
data.agg({'price':['sum','mean'],'quantity':get_max})
price quantity
get_max NaN 111.0
mean 2.86 NaN
sum 14.30 NaN
三、更多资源下载
微信搜索“老和山算法指南”获取更多下载链接与技术交流群
有问题可以私信博主,点赞关注的一般都会回复,一起努力,谢谢支持。