pandas group分组与agg聚合的实例

作者:xusworld 时间:2023-01-04 14:22:28 

如下:


import pandas as pd

df = pd.DataFrame({'Country':['China','China', 'India', 'India', 'America', 'Japan', 'China', 'India'],
    'Income':[10000, 10000, 5000, 5002, 40000, 50000, 8000, 5000],
    'Age':[5000, 4321, 1234, 4010, 250, 250, 4500, 4321]})

构造的数据如下:


Age Country Income
0 5000 China 10000
1 4321 China 10000
2 1234 India 5000
3 4010 India 5002
4 250 America 40000
5 250 Japan 50000
6 4500 China 8000
7 4321 India 5000

分组

单列分组


df_gb = df.groupby('Country')
for index, data in df_gb:
print(index)
print(data)

输出


America
Age Country Income
4 250 America 40000
China
Age Country Income
0 5000 China 10000
1 4321 China 10000
6 4500 China 8000
India
Age Country Income
2 1234 India 5000
3 4010 India 5002
7 4321 India 5000
Japan
Age Country Income
5 250 Japan 50000

多列分组


df_gb = df.groupby(['Country', 'Income'])
for (index1, index2), data in df_gb:
print((index1, index2))
print(data)

输出


('America', 40000)
Age Country Income
4 250 America 40000
('China', 8000)
Age Country Income
6 4500 China 8000
('China', 10000)
Age Country Income
0 5000 China 10000
1 4321 China 10000
('India', 5000)
Age Country Income
2 1234 India 5000
7 4321 India 5000
('India', 5002)
Age Country Income
3 4010 India 5002
('Japan', 50000)
Age Country Income
5 250 Japan 50000

聚合

对分组后数据进行聚合

默认情况对分组之后其他列进行聚合


df_agg = df.groupby('Country').agg(['min', 'mean', 'max'])
print(df_agg)

输出


Age     Income      
  min   mean max min   mean max
Country              
America 250 250.000000 250 40000 40000.000000 40000
China 4321 4607.000000 5000 8000 9333.333333 10000
India 1234 3188.333333 4321 5000 5000.666667 5002
Japan  250 250.000000 250 50000 50000.000000 50000

对分组后的部分列进行聚合

某些情况,只需要对部分数据进行不同的聚合操作,可以通过字典来构建


num_agg = {'Age':['min', 'mean', 'max']}
print(df.groupby('Country').agg(num_agg))

输出


Age    
  min   mean max
Country      
America 250 250.000000 250
China 4321 4607.000000 5000
India 1234 3188.333333 4321
Japan  250 250.000000 250
num_agg = {'Age':['min', 'mean', 'max'], 'Income':['min', 'max']}
print(df.groupby('Country').agg(num_agg))

输出


 Age     Income  
  min   mean max min max
Country          
America 250 250.000000 250 40000 40000
China 4321 4607.000000 5000 8000 10000
India 1234 3188.333333 4321 5000 5002
Japan  250 250.000000 250 50000 50000

补充:pandas——很全的groupby、agg,对表格数据分组与统计

我这篇groupby写的不好。太复杂了。其实实际上经常用的就那么几个。举个例子,把常用的往那一放就很容易理解和拿来用了。日后再写一篇。

groupby功能:分组

groupby + agg(聚集函数们): 分组后,对各组应用一些函数,如'sum',‘mean',‘max',‘min'…

groupby默认纵方向上分组,axis=0


DataFrame
import pandas as pd
import numpy as np

df = pd.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)

 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

分组,并对分组进行迭代


list(df.groupby(['key1']))#list后得到:[(group1),(group2),......]

[('a',  data1  data2 key1 key2
0 -0.410122 0.247895 a one
1 -0.627470 -0.989268 a two
4 -0.297191 0.954447 a one), ('b',  data1  data2 key1 key2
2 0.179488 -0.054570 b one
3 -0.299878 -1.640494 b two)]

list后得到:[(group1),(group2),…]

每个数据片(group)格式: (name,group)元组

1. 按key1(一个列)分组,其实是按key1的值

groupby对象支持迭代,产生一组二元元组:(分组名,数据块),(分组名,数据块)…


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

a
 data1  data2 key1 key2
0 -0.410122 0.247895 a one
1 -0.627470 -0.989268 a two
4 -0.297191 0.954447 a one
b
 data1  data2 key1 key2
2 0.179488 -0.054570 b one
3 -0.299878 -1.640494 b two

2. 按[key1, key2](多个列)分组

对于多重键,产生的一组二元元组:((k1,k2),数据块),((k1,k2),数据块)…

第一个元素是由键值组成的元组


for name,group in df.groupby(['key1','key2']):
print(name) #name=(k1,k2)
print(group)

('a', 'one')
 data1  data2 key1 key2
0 -0.410122 0.247895 a one
4 -0.297191 0.954447 a one
('a', 'two')
 data1  data2 key1 key2
1 -0.62747 -0.989268 a two
('b', 'one')
 data1 data2 key1 key2
2 0.179488 -0.05457 b one
('b', 'two')
 data1  data2 key1 key2
3 -0.299878 -1.640494 b two

3. 按函数分组

4. 按字典分组

5. 按索引级别分组

6.将函数跟数组、列表、字典、Series混合使用也不是问题,因为任何东西最终都会被转换为数组

将这些数据片段做成字典


dict(list(df.groupby(['key1'])))#dict(list())

{'a':  data1  data2 key1 key2
0 -0.410122 0.247895 a one
1 -0.627470 -0.989268 a two
4 -0.297191 0.954447 a one, 'b':  data1  data2 key1 key2
2 0.179488 -0.054570 b one
3 -0.299878 -1.640494 b two}

分组后进行一些统计、计算等

1. 分组后,返回一个含有分组大小的Series

按key1分组


df.groupby(['key1']).size()

key1
a 3
b 2
dtype: int64

dict(['a1','x2','e3'])

{'a': '1', 'e': '3', 'x': '2'}

按[key1,key2]分组


df.groupby(['key1','key2']).size()

key1 key2
a  one  2
 two  1
b  one  1
 two  1
dtype: int64

2. 对data1按key1进行分组,并计算data1列的平均值


df['data1'].groupby(df['key1']).mean()
#groupby没有进行任何的计算。它只是进行了一个分组

key1
a -0.444928
b -0.060195
Name: data1, dtype: float64

df.groupby(['key1'])['data1'].mean()#理解:对df按key1分组,并计算分组后df['data1']的均值
#等价于:df.groupby(['key1']).data1.mean()

key1
a -0.444928
b -0.060195
Name: data1, dtype: float64

说明:

groupby没有进行任何的计算。它只是进行了一个分组。

数据(Series)根据分组键进行了聚合,产生了一个新的Series,其索引为key1列中的唯一值。

这种索引操作所返回的对象是一个已分组的DataFrame(如果传入的是列表或数组)或已分组的Series


df.groupby(['key1'])['data1'].size()

key1
a 3
b 2
Name: data1, dtype: int64

3.对data1按[key1,key2]进行分组,并计算data1的平均值


df['data1'].groupby([df['key1'],df['key2']]).mean()

key1 key2
a  one -0.353657
 two -0.627470
b  one  0.179488
 two -0.299878
Name: data1, dtype: float64

df.groupby(['key1','key2'])['data1'].mean()
#等价于:df.groupby(['key1','key2']).data1'.mean()

key1 key2
a  one -0.353657
 two -0.627470
b  one  0.179488
 two -0.299878
Name: data1, dtype: float64

通过两个键对数据进行了分组,得到的Series具有一个层次化索引(由唯一的键对组成):


df.groupby(['key1','key2'])['data1'].mean().unstack()
key2onetwo
key1

a-0.353657-0.627470
b0.179488-0.299878

在上面这些示例中,分组键均为Series。实际上,分组键可以是任何长度适当的数组。非常灵活。

横方向上

按列的数据类型(df.dtypes)来分

df共两种数据类型:float64和object,所以会分为两组(dtype(‘float64'),数据片),(dtype(‘O'), 数据片)


list(df.groupby(df.dtypes, axis=1))

[(dtype('float64'),  data1  data2
0 -0.410122 0.247895
1 -0.627470 -0.989268
2 0.179488 -0.054570
3 -0.299878 -1.640494
4 -0.297191 0.954447), (dtype('O'), key1 key2
0 a one
1 a two
2 b one
3 b two
4 a one)]

agg的应用

groupby+agg 可以对groupby的结果同时应用多个函数

SeriesGroupBy的方法agg()参数:


aggregate(self, func_or_funcs, * args, ** kwargs)
func: function, string, dictionary, or list of string/functions

返回:aggregated的Series


s= pd.Series([10,20,30,40])
s

0 10
1 20
2 30
3 40
dtype: int64

for n,g in s.groupby([1,1,2,2]):
print(n)
print(g)

0 10
1 20
dtype: int64
2
2 30
3 40
dtype: int64

s.groupby([1,1,2,2]).min()
1
1 10
2 30
dtype: int64

#等价于这个:
s.groupby([1,1,2,2]).agg('min')

1 10
2 30
dtype: int64

s.groupby([1,1,2,2]).agg(['min','max'])#加[],func仅接受一个参数

minmax
11020
23040

常常这样用:

df


data1data2key1key2
0-0.4101220.247895aone
1-0.627470-0.989268atwo
20.179488-0.054570bone
3-0.299878-1.640494btwo
4-0.2971910.954447aone

比较下面,可以看出agg的用处:


df.groupby(['key1'])['data1'].min()

key1
a -0.627470
b -0.299878
Name: data1, dtype: float64

df.groupby(['key1'])['data1'].agg({'min'})

min
key1
a-0.627470
b-0.299878

#推荐用这个√
df.groupby(['key1']).agg({'data1':'min'})#对data1列,取各组的最小值,名字还是data1

data1
key1
a-0.627470
b-0.299878

#按key1分组后,aggregate各组data1的最小值和最大值:
df.groupby(['key1'])['data1'].agg({'min','max'})

maxmin
key1

a-0.297191-0.627470
b0.179488-0.299878

#推荐用这个√
df.groupby(['key1']).agg({'data1':['min','max']})

data1

minmax
key1

a-0.627470-0.297191
b-0.2998780.179488

可以对groupby的结果更正列名(不推荐用这个,哪怕在后面单独更改列名)


# 对data1,把min更名为a,max更名为b
df.groupby(['key1'])['data1'].agg({'a':'min','b':'max'})#这里的'min' 'max'为两个函数名

d:\python27\lib\site-packages\ipykernel_launcher.py:2: FutureWarning: using a dict on a Series for aggregation
is deprecated and will be removed in a future version

ab
key1

a-0.627470-0.297191
b-0.2998780.179488

重要技巧: groupby之后直接.reset_index()可以得到一个没有多级索引的DataFrame

之后可以通过df.rename({‘old_col1':‘new_col1',‘old_col2':‘new_col2',…})重命名

eg:


df1= df.groupby(['date'])['price'].agg({'sum','count'}).reset_index()

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。

来源:https://blog.csdn.net/u012706792/article/details/80892510

标签:pandas,group,agg
0
投稿

猜你喜欢

  • 一文讲清base64编码原理

    2023-04-10 23:51:48
  • Python标准库使用OrderedDict类的实例讲解

    2022-07-17 22:27:31
  • Centos7使用yum安装Mysql5.7.19的详细步骤

    2024-01-24 13:01:56
  • 基于OpenCV python3实现证件照换背景的方法

    2023-01-30 06:25:54
  • ASP.NET MVC使用区域(Area)功能

    2024-06-05 09:25:04
  • Mysql DateTime 查询问题解析

    2024-01-23 06:00:53
  • 简述Redis和MySQL的区别

    2024-01-25 01:18:34
  • 当达到输入长度时表单自动切换焦点

    2024-05-02 17:29:33
  • Vue不同项目之间传递、接收参数问题

    2024-04-30 10:47:06
  • python实现单例的两种方法解读

    2022-04-10 21:10:46
  • 执行python脚本并传入json数据格式参数方式

    2021-12-09 21:22:14
  • 浅谈tf.train.Saver()与tf.train.import_meta_graph的要点

    2022-06-02 09:59:32
  • 利用Python的tkinter模块实现界面化的批量修改文件名

    2023-08-30 20:45:15
  • 网页图片延时加载的js代码

    2024-04-22 13:22:41
  • JScript下Array对象的性能问题

    2009-02-15 12:28:00
  • Django 实现外键去除自动添加的后缀‘_id’

    2022-11-16 08:06:35
  • Python实现简单层次聚类算法以及可视化

    2023-09-04 00:16:21
  • Python range与enumerate函数区别解析

    2022-03-05 21:40:20
  • 由prototype_1.3.1进入javascript殿堂-类的初探

    2008-05-22 12:44:00
  • layui 富文本图片上传接口与普通按钮 文件上传接口的例子

    2024-05-22 10:36:28
  • asp之家 网络编程 m.aspxhome.com