groupby分组聚合和运算

本文是对《利用Python进行数据分析》中关于groupby进行分组聚合和运算的一个回顾性总结,整体而言,在过去的一年的工作中,用到groupby的场景还是蛮多的,尤其是利用它与相关函数的结合能解决非常多场景下的数据分析需求,也非常方便,是个重点。 

目录

groupby分组解析

groupby分组依据

groupby后的分组对象


groupby分组解析

groupby分组依据

groupby 分组依据:整体而言,分组键可以有多种形式,且类型不必相同:列表或数组,其长度与待分组的轴一样;表示DataFrame某个列名的值;字典或Series,给出待分组轴上的值与分组名之间的对应关系;函数,用于处理轴索引或索引中的各个标签。下面逐个讲解记录。
按照列名分组
        方式1-df直接以key
            实例1:

df = 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.groupby('key1')['data1'].mean()) # 这个同下面等价。相当于先key1分组,然后去其中data1列的值来计算均值。

输出

 <pandas.core.groupby.SeriesGroupBy object at 0x7fae8aed8350>
key1
a    0.746672
b   -0.537585
Name: data1, dtype: float64
                      
    方式2 -选serise按照series
            实例2:

 # 按key1进行分组,并计算data1列的平均值 
grouped=df['data1'].groupby(df['key1']) # 访问data1,并根据分组键(key1的所有值)调用groupby 。 
print(grouped)
print(grouped.mean())

  输出
 key1
a    0.746672
b   -0.537585
Name: data1, dtype: float64


按照series分组
这是对于选取series来根据另一个或多个series进行分组
        实例

#按照Series分组
means = df['data1'].groupby([df['key1'], df['key2']]).mean()
print(means)
# 上面的分组键均为Series。实际上,分组键可以是任何长度适当的数组 实际也可以穿入将列名当做分组键,但注意data1在后面了
# 注意多个分组键在运算后会形成层次化索引
print(df.groupby(['key1','key2'])['data1'].mean())
print(df.groupby(['key1','key2'])['data1'].mean().index)

  输出
       key1    key2
a     one     0.880536
      two     0.478943
b     one    -0.519439
      two    -0.555730
Name: data1, dtype: float64
key1  key2
a     one     0.880536
      two     0.478943
b     one    -0.519439
      two    -0.555730
Name: data1, dtype: float64
MultiIndex(levels=[[u'a', u'b'], [u'one', u'two']],
           labels=[[0, 0, 1, 1], [0, 1, 0, 1]],
           names=[u'key1', u'key2'])


按数组分组
由series来根据依据的数组进行分组, 实例

# 上面的分组键均为Series。实际上,分组键可以是任何长度适当的数组 
states=np.array(['Ohio', 'California', 'California', 'Ohio', 'Ohio'])
years = np.array([2005, 2005, 2006, 2005, 2006])
df['data1'].groupby([states,years]).mean()

 输出
 California  2005    0.478943
               2006   -0.519439
Ohio        2005   -0.380219
               2006    1.965781
Name: data1, dtype: float64

 

按字典分组
        实例:  假设已知列的分组关系,并希望根据分组计算列的和: 注意此,字典中传的key是对应dataframe中的column

people=DataFrame(np.random.randn(5,5),columns=['a','b','c','d','e'],index=['Joe','Steve','Wes','Jim','Travis'])
# 假设已知列的分组关系,并希望根据分组计算列的和: 注意此,字典中传的key是对应dataframe中的column
mapping={'a':'red','b':'red','c':'blue','d':'blue','e':'red','f':'orange'}
# 将这个分组关系字典传给groupby即可 
by_column=people.groupby(mapping,axis=1) # 注意此是对列的分组关系,因此要用axis=1
by_column.sum()

输出
              blue       red
Joe     0.780548 -3.128892
Steve   0.720225  1.705513
Wes    -2.956703 -2.197664
Jim     1.413643  0.743556
Travis -1.647382 -0.902466


按函数分组  
函数包括python与pandas自带的函数、自定义函数。一次还可传多个函数组成的list。
#实例1,按pandas自带的函数
grouped2=df.groupby(df.dtypes,axis=0)
print(grouped2)
输出
                <pandas.core.groupby.DataFrameGroupBy object at 0x7fae31765e50>

 #实例2 ,按python的函数如len 。注意 group by 可以传函数,通过函数进行分组。任何被当做分组键的函数都会在各个索引值index 上被调用一次,其返回值就会被用作分组索引名称,此即len的长度值

people=DataFrame(np.random.randn(5,5),columns=['a','b','c','d','e'],index=['Joe','Steve','Wes','Jim','Travis']) 
people.groupby(len).sum() # group by 可以传函数,通过函数进行分组。任何被当做分组键的函数都会在各个索引值index 上被调用一次,其返回值就会被用作分组索引名称,此即len的长度值

  输出
            a               b         c                      d         e
3  0.591569 -0.993608  0.798764 -0.791374  2.119639
5  0.886429 -2.001637 -0.371843  1.669025 -0.438570
6 -0.713544 -0.831154 -2.370232 -1.860761 -0.860757


按函数、数组、字典等混合使用也可以。本质上都是根据值的对应去分组
        实例: #注意: 对于 groupby , 将函数跟数组、列表、字典、Series 混合使用也不是问题,因为任何东西最终都会被转换为数组 

key_list=['one','one','one','two','two']
people.groupby([len,key_list]).min()

  输出
                   a               b                  c         d         e
3 one -0.539741 -1.296221  0.274992 -1.021228 -0.577087
  two  0.124121  0.302614  0.523772  0.000940  1.343810
5 one  0.886429 -2.001637 -0.371843  1.669025 -0.438570
6 two -0.713544 -0.831154 -2.370232 -1.860761 -0.860757


根据层次化索引的级别或者编号
首先,数据是含有层次化索引的df,层次化索引数据集最方便的地方就在于它能够根据索引级别进行聚合。要实现该目的,通过level 关键字传入级别编号或名称 即可。

        实例

columns=pd.MultiIndex.from_arrays([['US','US','US','JP','JP'],[1,3,5,1,3]],names=['city','tensor'])
hier_df=DataFrame(np.random.randn(4,5),columns=columns)
print(hier_df)
print(hier_df.columns)
# 注意传入的names里的值
print(hier_df.groupby(level='city',axis=1).count())

 输出
 city                  US              JP          
tensor         1         3         5         1         3
0       0.051316 -1.157719  0.816707  0.433610  1.010737
1       1.824875 -0.997518  0.850591 -0.131578  0.912414
2       0.188211  2.169461 -0.114928  2.003697  0.029610
3       0.795253  0.118110 -0.748532  0.584970  0.152677
MultiIndex(levels=[[u'JP', u'US'], [1, 3, 5]],
           labels=[[1, 1, 1, 0, 0], [0, 1, 2, 0, 1]],
           names=[u'city', u'tensor'])
city  JP  US
0      2   3
1      2   3
2      2   3
3      2   3

groupby后的分组对象


   groupby 对象支持迭代,可以产生一组二元元组(由分组名和数据块组成)
        实例1

 for name ,group in df.groupby('key1'):
    print(name)
    print(group)

   输出
 a
      data1     data2 key1 key2
0 -0.204708  1.393406    a  one
1  0.478943  0.092908    a  two
4  1.965781  1.246435    a  one
b
      data1     data2 key1 key2
2 -0.519439  0.281746    b  one
3 -0.555730  0.769023    b  two

实例2:  groupby 后套个list 可以直接转换为字典! 得到的字典的key为groupby对象的值

pieces=dict(list(df.groupby('key1'))) # groupby 后套个list 可以直接转换为字典! 得到的字典的key为groupby对象的值
pieces['b']

  输出
data1     data2 key1 key2
2 -0.519439  0.281746    b  one
3 -0.555730  0.769023    b  two
从groupby后的对象中选取一个或一组列
 实例 : 注意 此处同下面的对比,此处传入的是['data2'] ,如果传入的是 列表或数组,如此处,得到的返回的是 已分组的 DataFrame .下面传的是单个值 'data2',则得到返回的是 已分组的 Series 

s1=df.groupby(['key1','key2'])[['data2','data1']].mean() # 注意 此处同下面的对比,此处传入的是['data2'] ,如果传入的是 列表或数组,如此处,得到的返回的是 已分组的 DataFrame .下面传的是单个值 'data2',则得到返回的是 已分组的 Series 
print(type(s1))
print(s1)

   输出
<class 'pandas.core.frame.DataFrame'>
              data2     data1
key1 key2                    
a    one   1.319920  0.880536
     two   0.092908  0.478943
b    one   0.281746 -0.519439
     two   0.769023 -0.555730

s2=df.groupby(['key1','key2'])['data2'].mean()
print(type(s2))# 此得到则为series
print(s2)
# print(s2.columns)
print(s2.index)

 输出
<class 'pandas.core.series.Series'>
key1  key2
a     one     1.319920
      two     0.092908
b     one     0.281746
      two     0.769023
Name: data2, dtype: float64
MultiIndex(levels=[[u'a', u'b'], [u'one', u'two']],
           labels=[[0, 0, 1, 1], [0, 1, 0, 1]],
           names=[u'key1', u'key2'])

后续小结将继续围绕groupby 从如下方面进行回顾

利用groupby进行数据聚合

分组级运算和转换

透视表

交叉表

案例

鸣谢与参考:

《利用python进行数据分析》

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值