pandas的聚合操作: groupyby与agg

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

三、更多资源下载

微信搜索“老和山算法指南”获取更多下载链接与技术交流群
在这里插入图片描述
有问题可以私信博主,点赞关注的一般都会回复,一起努力,谢谢支持。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Liangjun_Feng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值