pandas中GroupBy:分割,应用和组合(最全解析)

1、groupby主要用于数据的某些标签或索引的局部进行累计分析,大致过程为输入,分割,应用,组合。

import numpy as np
import pandas as pd
df = pd.DataFrame({'key':['A','B','C','A','B','C'],
                   'data':range(6)},columns = ['key','data'])

OUT:

  key  data
0   A     0
1   B     1
2   C     2
3   A     3
4   B     4
5   C     5
df.groupby('key')
#返回值为<pandas.core.groupby.groupby.DataFrameGroupBy object at 0x0000008F017F9DA0>
#返回值不是一个DataFrame对象,而是DataFrameGroupBy对象。可以将它看作是特殊形式的DataFrame,里
#隐藏着若干组数据,但是在没有应用累计函数之前不会计算,可以理解为“延迟计算”。
df.groupby('key').sum()
OUT:
     data
key      
A       3
B       5
C       7

2、Group对象

(1)按列取值:GroupBy对象与DataFrame一样,支持按列取值,并返回一个修改过的GroupBy对象;

(2)按组迭代:GroupBy对象支持直接按组迭代,返回每一组都是Series或DataFrame;

3、累计,过滤,转换,应用(aggregate(),filter(),transform(),apply())

df = pd.DataFrame({'key':['A','B','C','A','B','C'],
                   'data1':range(6),
                   'data2':rng.randint(0,10,6)},
                    columns = ['key','data1','data2'])
OUT:
    key  data1  data2
0   A      0      5
1   B      1      0
2   C      2      3
3   A      3      3
4   B      4      7
5   C      5      9

(1)累计

df.groupby('key').aggregate(['min',np.median,max])
OUT:
data1            data2           
      min median max   min median max
key                                  
A       0    1.5   3     3    4.0   5
B       1    2.5   4     0    3.5   7
C       2    3.5   5     3    6.0   9

#指定不同列需要累积的函数
df.groupby('key').aggregate({'data1':'min',
                              'data2':'max'})
OUT:
     data1  data2
key              
A        0      5
B        1      7
C        2      9

(2)过滤:过滤操作可以让你按照分组的属性丢弃若干数据。

#只保留标准差超过某个阈值的组
def filter_func(x):
    return x['data2'].std() > 4
print(df)
print(df.groupby('key').std())
print(df.groupby('key').filter(filter_func))
#filter()函数会返回一个布尔值,表示每组是否通过过滤。由于A组‘data2’列的标准差不大于4,所以被丢
##弃。

OUT:
  key  data1  data2
0   A      0      5
1   B      1      0
2   C      2      3
3   A      3      3
4   B      4      7
5   C      5      9
       data1     data2
key                   
A    2.12132  1.414214
B    2.12132  4.949747
C    2.12132  4.242641
  key  data1  data2
1   B      1      0
2   C      2      3
4   B      4      7
5   C      5      9

(3)转换。累计操作返回的是对组内全部数据缩减的结果,而转换操作会返回一个全新的数据。数据经过转换之后,其形状与原来的输入数据是一样的。常见的例子就是将每一组的样本数据减去各组对应的均值,实现数据标准化。

#将数据标准化
sd = df.groupby('key').transform(lambda x : x-x.mean())
print(sd)

OUT:
   data1  data2
0   -1.5    1.0
1   -1.5   -3.5
2   -1.5   -3.0
3    1.5   -1.0
4    1.5    3.5
5    1.5    3.0

(4)应用,apply()方法可以让你在每个组上应用任意方法。这个函数输入一个DataFrame,返回一个Pandas对象(DataFrame或Series)或者一个标量(scalar,单个数值)。组合操作会对应返回结果类型。

#用apply()方法将第一列数据以第二列的和为基数进行标准化
def norm_by_data2(x):
    #x是一个分组数据的DataFrame
    x['data1'] /= x['data2'].sum()
    return x

print(df)
print(df.groupby('key').apply(norm_by_data2))

OUT:
  key  data1  data2
0   A      0      5
1   B      1      0
2   C      2      3
3   A      3      3
4   B      4      7
5   C      5      9
  key     data1  data2
0   A  0.000000      5
1   B  0.142857      0
2   C  0.166667      3
3   A  0.375000      3
4   B  0.571429      7
5   C  0.416667      9

4、设置分给键:前面的例子一直用列名分割DataFrame,这只是众多分组操作中的一种。

(1)将列表,数组,Series或索引作为分组键。分组键可以是长度与DataFrame匹配的任意series或列表。

L = [0,1,0,1,2,0]
print(df)
print(df.groupby(L).sum())#分别对第1,3,6; 2,4 和5行求和

OUT:
  key  data1  data2
0   A      0      5
1   B      1      0
2   C      2      3
3   A      3      3
4   B      4      7
5   C      5      9
   data1  data2
0      7     17
1      4      3
2      4      7

(2)用字典或Series将索引映射到分组名称。

df2 = df.set_index('key')
mapping = {'A':'vpwel','B':'consonant','C':'consonant'}
print(df)
print(df2)
print(df2.groupby(mapping).sum()) 
#注意不能直接print(df.groupby(mapping).sum())
#此时out结果为
#Empty DataFrame
#Columns: [data1, data2]
#Index: []

OUT:
 key  data1  data2
0   A      0      5
1   B      1      0
2   C      2      3
3   A      3      3
4   B      4      7
5   C      5      9
     data1  data2
key              
A        0      5
B        1      0
C        2      3
A        3      3
B        4      7
C        5      9
           data1  data2
consonant     12     19
vpwel          3      8

(3)任意Python函数,可以将任意Python函数传入groupby,函数映射到索引,然后新的分组输出

 print(df2.groupby(str.lower).mean())
#将索引转换为小写

OUT:
   data1  data2
a    1.5    4.0
b    2.5    3.5
c    3.5    6.0

(4)多个有效键,构成的列表

 print(df2.groupby([str.lower,mapping]).mean())



OUT:
             data1  data2
a vpwel        1.5    4.0
b consonant    2.5    3.5
c consonant    3.5    6.0

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值