• 售前

  • 售后

热门帖子
入门百科

pandas group分组与agg聚合的实例

[复制链接]
淡淡如菊795 显示全部楼层 发表于 2021-10-26 13:46:47 |阅读模式 打印 上一主题 下一主题
如下:
  1. import pandas as pd
  2. df = pd.DataFrame({'Country':['China','China', 'India', 'India', 'America', 'Japan', 'China', 'India'],
  3.      'Income':[10000, 10000, 5000, 5002, 40000, 50000, 8000, 5000],
  4.      'Age':[5000, 4321, 1234, 4010, 250, 250, 4500, 4321]})
复制代码
构造的数据如下:
  1. Age Country Income
  2. 0 5000 China 10000
  3. 1 4321 China 10000
  4. 2 1234 India 5000
  5. 3 4010 India 5002
  6. 4 250 America 40000
  7. 5 250 Japan 50000
  8. 6 4500 China 8000
  9. 7 4321 India 5000
复制代码
分组

单列分组
  1. df_gb = df.groupby('Country')
  2. for index, data in df_gb:
  3. print(index)
  4. print(data)
复制代码
输出
  1. America
  2. Age Country Income
  3. 4 250 America 40000
  4. China
  5. Age Country Income
  6. 0 5000 China 10000
  7. 1 4321 China 10000
  8. 6 4500 China 8000
  9. India
  10. Age Country Income
  11. 2 1234 India 5000
  12. 3 4010 India 5002
  13. 7 4321 India 5000
  14. Japan
  15. Age Country Income
  16. 5 250 Japan 50000
复制代码
多列分组
  1. df_gb = df.groupby(['Country', 'Income'])
  2. for (index1, index2), data in df_gb:
  3. print((index1, index2))
  4. print(data)
复制代码
输出
  1. ('America', 40000)
  2. Age Country Income
  3. 4 250 America 40000
  4. ('China', 8000)
  5. Age Country Income
  6. 6 4500 China 8000
  7. ('China', 10000)
  8. Age Country Income
  9. 0 5000 China 10000
  10. 1 4321 China 10000
  11. ('India', 5000)
  12. Age Country Income
  13. 2 1234 India 5000
  14. 7 4321 India 5000
  15. ('India', 5002)
  16. Age Country Income
  17. 3 4010 India 5002
  18. ('Japan', 50000)
  19. Age Country Income
  20. 5 250 Japan 50000
复制代码
聚合

对分组后数据进行聚合

默认情况对分组之后其他列进行聚合
  1. df_agg = df.groupby('Country').agg(['min', 'mean', 'max'])
  2. print(df_agg)
复制代码
输出
  1. Age     Income      
  2.    min   mean max min   mean max
  3. Country              
  4. America 250 250.000000 250 40000 40000.000000 40000
  5. China 4321 4607.000000 5000 8000 9333.333333 10000
  6. India 1234 3188.333333 4321 5000 5000.666667 5002
  7. Japan  250 250.000000 250 50000 50000.000000 50000
复制代码
对分组后的部分列进行聚合

某些情况,只需要对部分数据进行差别的聚合操作,可以通过字典来构建
  1. num_agg = {'Age':['min', 'mean', 'max']}
  2. print(df.groupby('Country').agg(num_agg))
复制代码
输出
  1. Age     
  2.    min   mean max
  3. Country      
  4. America 250 250.000000 250
  5. China 4321 4607.000000 5000
  6. India 1234 3188.333333 4321
  7. Japan  250 250.000000 250
  8. num_agg = {'Age':['min', 'mean', 'max'], 'Income':['min', 'max']}
  9. print(df.groupby('Country').agg(num_agg))
复制代码
输出
  1.   Age     Income  
  2.    min   mean max min max
  3. Country         
  4. America 250 250.000000 250 40000 40000
  5. China 4321 4607.000000 5000 8000 10000
  6. India 1234 3188.333333 4321 5000 5002
  7. Japan  250 250.000000 250 50000 50000
复制代码
增补:pandas——很全的groupby、agg,对表格数据分组与统计
我这篇groupby写的不好。太复杂了。着实现实上常常用的就那么几个。举个例子,把常用的往那一放就很轻易明白和拿来用了。日后再写一篇。
groupby功能:分组
groupby + agg(聚集函数们): 分组后,对各组应用一些函数,如'sum',‘mean',‘max',‘min'…
groupby默认纵方向上分组,axis=0
  1. DataFrame
  2. import pandas as pd
  3. import numpy as np
复制代码
  1. df = pd.DataFrame({'key1':['a', 'a', 'b', 'b', 'a'],
  2.      'key2':['one', 'two', 'one', 'two', 'one'],
  3.      'data1':np.random.randn(5),
  4.      'data2':np.random.randn(5)})
  5. print(df)
复制代码
  1.   data1  data2 key1 key2
  2. 0 -0.410122 0.247895 a one
  3. 1 -0.627470 -0.989268 a two
  4. 2 0.179488 -0.054570 b one
  5. 3 -0.299878 -1.640494 b two
  6. 4 -0.297191 0.954447 a one
复制代码
分组,并对分组进行迭代
  1. list(df.groupby(['key1']))#list后得到:[(group1),(group2),......]
复制代码
  1. [('a',  data1  data2 key1 key2
  2. 0 -0.410122 0.247895 a one
  3. 1 -0.627470 -0.989268 a two
  4. 4 -0.297191 0.954447 a one), ('b',  data1  data2 key1 key2
  5. 2 0.179488 -0.054570 b one
  6. 3 -0.299878 -1.640494 b two)]
复制代码
list后得到:[(group1),(group2),…]
每个数据片(group)格式: (name,group)元组
1. 按key1(一个列)分组,着实是按key1的值
groupby对象支持迭代,产生一组二元元组:(分组名,数据块),(分组名,数据块)…
  1. for name,group in df.groupby(['key1']):
  2. print(name)
  3. print(group)
复制代码
  1. a
  2.   data1  data2 key1 key2
  3. 0 -0.410122 0.247895 a one
  4. 1 -0.627470 -0.989268 a two
  5. 4 -0.297191 0.954447 a one
  6. b
  7.   data1  data2 key1 key2
  8. 2 0.179488 -0.054570 b one
  9. 3 -0.299878 -1.640494 b two
复制代码
2. 按[key1, key2](多个列)分组
对于多重键,产生的一组二元元组:((k1,k2),数据块),((k1,k2),数据块)…
第一个元素是由键值构成的元组
  1. for name,group in df.groupby(['key1','key2']):
  2. print(name) #name=(k1,k2)
  3. print(group)
复制代码
  1. ('a', 'one')
  2.   data1  data2 key1 key2
  3. 0 -0.410122 0.247895 a one
  4. 4 -0.297191 0.954447 a one
  5. ('a', 'two')
  6.   data1  data2 key1 key2
  7. 1 -0.62747 -0.989268 a two
  8. ('b', 'one')
  9.   data1 data2 key1 key2
  10. 2 0.179488 -0.05457 b one
  11. ('b', 'two')
  12.   data1  data2 key1 key2
  13. 3 -0.299878 -1.640494 b two
复制代码
3. 按函数分组
4. 按字典分组
5. 按索引级别分组
6.将函数跟数组、列表、字典、Series混淆利用也不是题目,由于任何东西终极都会被转换为数组
将这些数据片断做成字典
  1. dict(list(df.groupby(['key1'])))#dict(list())
复制代码
  1. {'a':  data1  data2 key1 key2
  2. 0 -0.410122 0.247895 a one
  3. 1 -0.627470 -0.989268 a two
  4. 4 -0.297191 0.954447 a one, 'b':  data1  data2 key1 key2
  5. 2 0.179488 -0.054570 b one
  6. 3 -0.299878 -1.640494 b two}
复制代码
分组后进行一些统计、盘算等
1. 分组后,返回一个含有分组大小的Series
按key1分组
  1. df.groupby(['key1']).size()
复制代码
  1. key1
  2. a 3
  3. b 2
  4. dtype: int64
复制代码
  1. dict(['a1','x2','e3'])
  2. {'a': '1', 'e': '3', 'x': '2'}
复制代码
按[key1,key2]分组
  1. df.groupby(['key1','key2']).size()
复制代码
  1. key1 key2
  2. a  one  2
  3.   two  1
  4. b  one  1
  5.   two  1
  6. dtype: int64
复制代码
2. 对data1按key1进行分组,并盘算data1列的匀称值
  1. df['data1'].groupby(df['key1']).mean()
  2. #groupby没有进行任何的计算。它只是进行了一个分组
复制代码
  1. key1
  2. a -0.444928
  3. b -0.060195
  4. Name: data1, dtype: float64
复制代码
  1. df.groupby(['key1'])['data1'].mean()#理解:对df按key1分组,并计算分组后df['data1']的均值
  2. #等价于:df.groupby(['key1']).data1.mean()
复制代码
  1. key1
  2. a -0.444928
  3. b -0.060195
  4. Name: data1, dtype: float64
复制代码
说明:
groupby没有进行任何的盘算。它只是进行了一个分组。
数据(Series)根据分组键进行了聚合,产生了一个新的Series,其索引为key1列中的唯一值。
这种索引操作所返回的对象是一个已分组的DataFrame(假如传入的是列表或数组)或已分组的Series
  1. df.groupby(['key1'])['data1'].size()
复制代码
  1. key1
  2. a 3
  3. b 2
  4. Name: data1, dtype: int64
复制代码
3.对data1按[key1,key2]进行分组,并盘算data1的匀称值
  1. df['data1'].groupby([df['key1'],df['key2']]).mean()
复制代码
  1. key1 key2
  2. a  one -0.353657
  3.   two -0.627470
  4. b  one  0.179488
  5.   two -0.299878
  6. Name: data1, dtype: float64
复制代码
  1. df.groupby(['key1','key2'])['data1'].mean()
  2. #等价于:df.groupby(['key1','key2']).data1'.mean()
复制代码
  1. key1 key2
  2. a  one -0.353657
  3.   two -0.627470
  4. b  one  0.179488
  5.   two -0.299878
  6. Name: data1, dtype: float64
复制代码
通过两个键对数据进行了分组,得到的Series具有一个条理化索引(由唯一的键对构成):
  1. df.groupby(['key1','key2'])['data1'].mean().unstack()
复制代码
      key2      one      two              key1                              a      -0.353657      -0.627470              b      0.179488      -0.299878    在上面这些示例中,分组键均为Series。现实上,分组键可以是任何长度适当的数组。非常机动。
横方向上
按列的数据类型(df.dtypes)来分
df共两种数据类型:float64和object,所以会分为两组(dtype(‘float64'),数据片),(dtype(‘O'), 数据片)
  1. list(df.groupby(df.dtypes, axis=1))
复制代码
  1. [(dtype('float64'),  data1  data2
  2. 0 -0.410122 0.247895
  3. 1 -0.627470 -0.989268
  4. 2 0.179488 -0.054570
  5. 3 -0.299878 -1.640494
  6. 4 -0.297191 0.954447), (dtype('O'), key1 key2
  7. 0 a one
  8. 1 a two
  9. 2 b one
  10. 3 b two
  11. 4 a one)]
复制代码
agg的应用
groupby+agg 可以对groupby的结果同时应用多个函数
SeriesGroupBy的方法agg()参数:
  1. aggregate(self, func_or_funcs, * args, ** kwargs)
  2. func: function, string, dictionary, or list of string/functions
复制代码
返回:aggregated的Series
  1. s= pd.Series([10,20,30,40])
  2. s
复制代码
  1. 0 10
  2. 1 20
  3. 2 30
  4. 3 40
  5. dtype: int64
复制代码
  1. for n,g in s.groupby([1,1,2,2]):
  2. print(n)
  3. print(g)
复制代码
  1. 0 10
  2. 1 20
  3. dtype: int64
  4. 2
  5. 2 30
  6. 3 40
  7. dtype: int64
复制代码
  1. s.groupby([1,1,2,2]).min()
  2. 1
  3. 1 10
  4. 2 30
  5. dtype: int64
复制代码
  1. #等价于这个:
  2. s.groupby([1,1,2,2]).agg('min')
复制代码
  1. 1 10
  2. 2 30
  3. dtype: int64
复制代码
  1. s.groupby([1,1,2,2]).agg(['min','max'])#加[],func仅接受一个参数
复制代码
            min      max                  1      10      20              2      30      40    常常这样用:
  1. df
复制代码
            data1      data2      key1      key2                  0      -0.410122      0.247895      a      one              1      -0.627470      -0.989268      a      two              2      0.179488      -0.054570      b      one              3      -0.299878      -1.640494      b      two              4      -0.297191      0.954447      a      one    比力下面,可以看出agg的用处:
  1. df.groupby(['key1'])['data1'].min()
复制代码
  1. key1
  2. a -0.627470
  3. b -0.299878
  4. Name: data1, dtype: float64
复制代码
  1. df.groupby(['key1'])['data1'].agg({'min'})
复制代码
            min              key1                        a      -0.627470              b      -0.299878   
  1. #推荐用这个√
  2. df.groupby(['key1']).agg({'data1':'min'})#对data1列,取各组的最小值,名字还是data1
复制代码
            data1              key1                        a      -0.627470              b      -0.299878   
  1. #按key1分组后,aggregate各组data1的最小值和最大值:
  2. df.groupby(['key1'])['data1'].agg({'min','max'})
复制代码
            max      min              key1                              a      -0.297191      -0.627470              b      0.179488      -0.299878   
  1. #推荐用这个√
  2. df.groupby(['key1']).agg({'data1':['min','max']})
复制代码
            data1                    min      max              key1                              a      -0.627470      -0.297191              b      -0.299878      0.179488    可以对groupby的结果更正列名(不保举用这个,哪怕在后面单独更改列名)
  1. # 对data1,把min更名为a,max更名为b
  2. df.groupby(['key1'])['data1'].agg({'a':'min','b':'max'})#这里的'min' 'max'为两个函数名
复制代码
  1. d:\python27\lib\site-packages\ipykernel_launcher.py:2: FutureWarning: using a dict on a Series for aggregation
  2. is deprecated and will be removed in a future version
复制代码
            a      b              key1                              a      -0.627470      -0.297191              b      -0.299878      0.179488    重要技巧: groupby之后直接.reset_index()可以得到一个没有多级索引的DataFrame
之后可以通过df.rename({‘old_col1':‘new_col1',‘old_col2':‘new_col2',…})重定名
eg:
  1. df1= df.groupby(['date'])['price'].agg({'sum','count'}).reset_index()
复制代码
以上为个人经验,渴望能给各人一个参考,也渴望各人多多支持草根技术分享。如有错误或未思量完全的地方,望不吝见教。

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作