pandas中的数据处理利器-groupby

在数据分析中,常常有这样的场景,需要对不同类别的数据,分别进行处理,然后再将处理之后的内容合并,作为结果输出。对于这样的场景,就需要借助灵活的groupby功能来处理。

groupby的操作过程如下

  1. split,  第一步,根据某一个或者多个变量的组合,将输入数据分成多个group

  2. apply, 第二步, 对每个group对应的数据进行处理

  3. combine, 第三步,将分组处理的结果合并起来,形成一个新的数据

图示如下

上述例子在python中的实现过程如下

>>> import numpy as np
>>> import pandas as pd
>>> df = pd.DataFrame({'x':['a','a','b','b','c','c'],'y':[2,4,0,5,5,10]})
>>> df
   x y
0 a 2
1 a 4
2 b 0
3 b 5
4 c 5
5 c 10


>>> df.groupby('x').mean()
     y
x
a 3.0
b 2.5
c 7.5

上述代码实现的是分组求均值的操作,通过groupby方法,首选根据x标签的内容分为a,b,c3组,然后对每组求均值,最后将结果进行合并。

groupby函数的返回值为为DataFrameGroupBy对象,有以下几个基本属性和方法

>>> grouped = df.groupby('x')
>>> grouped
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x06E94FA0>
# groups属性,返回值为字典,key是分组的类别
>>> grouped.groups
{'a': Int64Index([0, 1], dtype='int64'), 'b': Int64Index([2, 3], dtype='int64'), 'c': Int64Index([4, 5], dtype='int64')}
# len函数可以获得分组后的组别数
>>> len(grouped.groups)
3
# get_group方法可以获得每个group对应的数据框
>>> grouped.get_group('a')
   x y
0 a 2
1 a 4
>>> grouped.get_group('b')
   x y
2 b 0
3 b 5

# 遍历group
>>> for name, group in grouped:
... print(name)
... print(group)
...
a
   x y
0 a 2
1 a 4
b
   x y
2 b 0
3 b 5
c
   x y
4 c 5
5 c 10

pandas中的groupby实际上非常的灵活且强大,具体的操作技巧有以下几种

1. 分组方式

分组的依据既可以是单个标签,也可以是多个标签的组合,示例如下

>>> df = pd.DataFrame({'id':[1, 2, 3, 4],
... 'class':['a','a','b','b'],
... 'sex':['male', 'female', 'male', 'female'],
... 'age':[26, 16, 28, 30],
... })
>>>
>>> df
   id class     sex  age
0   1     a male 26
1   2     a female 16
2   3     b male 28
3   4     b female 30

# 单个列标签进行分组
>>> df.groupby('class')

# 多个列标签的组合,用列表的形式声明
>>> df.groupby(['class','sex'])

# 用行标签分组
>>> arrays = [['Falcon', 'Falcon', 'Parrot', 'Parrot'],
... ['Captive', 'Wild', 'Captive', 'Wild']]
>>> index = pd.MultiIndex.from_arrays(arrays, names=('Animal', 'Type'))
>>> df = pd.DataFrame({'Max Speed': [390., 350., 30., 20.]},
... index=index)
>>> df
                Max Speed
Animal Type
Falcon Captive 390.0
       Wild 350.0
Parrot Captive 30.0
       Wild 20.0

# 针对行标签为multiindex的情况,用level指定分组的标签
# 既可以是数字索引
>>> df.groupby(level=0).mean()
        Max Speed
Animal
Falcon 370.0
Parrot 25.0
# 也可以是name属性
>>> df.groupby(level="Type").mean()
         Max Speed
Type
Captive 210.0
Wild 185.0

2. 分组处理

分组处理就是对每个分组进行相同的操作,groupby的返回对象并不是一个DataFrame,   所以无法直接使用DataFrame的一些操作函数。

针对一些常用的功能,groupby提供了一些函数来直接操作DataFrameGroupBy对象, 比如统计个数,求和,求均值等,示例如下

# 计算每个group的个数
>>> df.groupby('x').count()
# 计算每个group的个数
>>> df.groupby('x').size()
# 求和
>>> df.groupby('x').sum()
# 求均值
>>> df.groupby('x').mean()
# 求中位数
>>> df.groupby('x').median()
# 求方差
>>> df.groupby('x').var()
# 求标准差
>>> df.groupby('x').std()
# 求最小值
>>> df.groupby('x').min()
# 求最大值
>>> df.groupby('x').max()

这里只是列举了部分函数,完整列表请参见API。通过aggregate方法则可以灵活的使用各种函数,用法如下

>>> df = pd.DataFrame({'x':['a','a','b','b','c','c'],'y':[2,4,0,5,5,10]})
# 一次使用一个函数进行处理
>>> df.groupby('x').aggregate(np.mean)
     y
x
a 3.0
b 2.5
c 7.5
# agg是aggregate的简写
>>> df.groupby('x').agg(np.mean)
     y
x
a 3.0
b 2.5
c 7.5
# 一次使用多种函数进行处理
>>> df.groupby('x').agg([np.sum, np.mean])
    y
  sum mean
x
a 6 3.0
b 5 2.5
c 15 7.5
# 自定义输出的列标签
>>> df.groupby('x').agg([np.sum,np.mean]).rename(columns={'sum':'cus_sum','mean':'cus_mean'})
        y
  cus_sum cus_mean
x
a 6 3.0
b 5 2.5
c 15 7.5


>>> df = pd.DataFrame({'x':['a','a','b','b','c','c'],'y':[2,4,0,5,5,10],'z':[4.0,2.1,3.5,4.2,3.8,4.7]})
>>> df
   x y z
0 a 2 4.0
1 a 4 2.1
2 b 0 3.5
3 b 5 4.2
4 c 5 3.8
5 c 10 4.7
# 同一列用不用函数进行处理
>>> df.groupby('x').agg(min=('y', 'min'), max=('y', 'max'))
   min max
x
a 2 4
b 0 5
c 5 10
# 不同列用不同函数进行处理
>>> df.groupby('x').agg(min=('y', 'min'), max=('z', 'max'))
   min max
x
a 2 4.0
b 0 4.2
c 5 4.7
# 不同列用不同函数进行处理
>>> df.groupby('x').agg({'y':'mean','z':'sum'})
     y z
x
a 3.0 6.1
b 2.5 7.7
c 7.5 8.5

3. 分组过滤

当需要根据某种条件对group进行过滤时,可以使用filter方法,用法如下

>>> df = pd.DataFrame({'x':['a','a','b','b','c','c'],'y':[2,4,0,5,5,10]})
>>> df
   x y
0 a 2
1 a 4
2 b 0
3 b 5
4 c 5
5 c 10

>>> df.groupby('x').filter(lambda x: x.mean() > 2.5)
   x y
0 a 2
1 a 4
4 c 5
5 c 10

4. 汇总数据

transform方法返回一个和输入的原始数据相同尺寸的数据框,常用于在原始数据框的基础上增加新的一列分组统计数据,用法如下

>>> df = pd.DataFrame({'x':['a','a','b','b','c','c'],'y':[2,4,0,5,5,10]})
>>> df
   x y
0 a 2
1 a 4
2 b 0
3 b 5
4 c 5
5 c 10

# 输出结果的行数和输入的原始数据框相同
# 内容为分组统计的结果
>>> df.groupby('x').transform(lambda x:x.count())
   y
0 2
1 2
2 2
3 2
4 2
5 2
# 通过索引操作符,在原始数据框的基础上添加汇总列
>>> df['mean_size'] = df.groupby('x').transform(lambda x:x.count())
>>> df
   x y mean_size
0 a 2 2
1 a 4 2
2 b 0 2
3 b 5 2
4 c 5 2
5 c 10 2

5. apply

apply相比agg, 更加的灵活,用法如下

>>> df = pd.DataFrame({'x':['a','a','b','b','c','c'],'y':[2,4,0,5,5,10]})
>>> df
   x y
0 a 2
1 a 4
2 b 0
3 b 5
4 c 5
5 c 10

>>> df.groupby('x').apply(lambda x:x.count())
   x y
x
a 2 2
b 2 2
c 2 2

>>> df.groupby('x').apply(lambda x:x - x.count())
   y
0 0
1 2
2 -2
3 3
4 3
5 8

pandas中的groupby功能非常的灵活强大,可以极大提高数据处理的效率。

·end·

—如果喜欢,快分享给你的朋友们吧—

原创不易,欢迎收藏,点赞,转发!生信知识浩瀚如海,在生信学习的道路上,让我们一起并肩作战!

本公众号深耕耘生信领域多年,具有丰富的数据分析经验,致力于提供真正有价值的数据分析服务,擅长个性化分析,欢迎有需要的老师和同学前来咨询。

  更多精彩

  写在最后

转发本文至朋友圈,后台私信截图即可加入生信交流群,和小伙伴一起学习交流。

扫描下方二维码,关注我们,解锁更多精彩内容!

一个只分享干货的

生信公众号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值