今天来介绍pandas中一个很有用的函数groupby,其实和hive中的groupby的效果是一样的,区别在于两种语言的写法问题。groupby在Python中的分组统计中很有用~
groupby:
首先创建数据:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
import pandas as pd
import numpy as np
df = pd.DataFrame({ 'A' : [ 'a' , 'b' , 'a' , 'c' , 'a' , 'c' , 'b' , 'c' ],
'B' : [ 2 , 7 , 1 , 3 , 3 , 2 , 4 , 8 ],
'C' : [ 100 , 87 , 96 , 130 , 105 , 87 , 96 , 155 ]})
df
Out[ 2 ]:
A B C
0 a 2 100
1 b 7 87
2 a 1 96
3 c 3 130
4 a 3 105
5 c 2 87
6 b 4 96
|
pandas中groupby的基本操作:
1、按A列进行分组,求B、C两列的均值:
1
2
3
4
5
6
7
|
df.groupby( 'A' ).mean()
Out[ 6 ]:
B C
A
a 2.000000 100.333333
b 5.500000 91.500000
c 4.333333 124.000000
|
当然也可以按照多列进行分组,获取其他列的均值:
1
2
3
4
5
6
7
8
9
10
11
12
|
df.groupby([ 'A' , 'B' ]).mean()
Out[ 7 ]:
C
A B
a 1 96
2 100
3 105
b 4 96
7 87
c 2 87
3 130
8 155
|
2、分组后,选择列进行计算:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
data = df.groupby( 'A' )
data[ 'B' ].std()
Out[ 11 ]:
A
a 1.00000
b 2.12132
c 3.21455
Name: B, dtype: float64
#选择B、C两列
data[ 'B' , 'C' ].mean()
Out[ 12 ]:
B C
A
a 2.000000 100.333333
b 5.500000 91.500000
c 4.333333 124.000000
|
3、按A进行分组后,可以对不同的列采用不同的聚合方法(ps:这一点就和hive很相像了)
1
2
3
4
5
6
7
|
data.agg({ 'B' : 'mean' , 'C' : 'sum' }) #B列均值,C列汇总
Out[ 14 ]:
C B
A
a 301 2.000000
b 183 5.500000
c 372 4.333333
|
4、如果按照A进行分组后,对多列采用相同的聚合方法,我们可以借助apply函数:
1
2
3
4
5
6
7
|
df.groupby( 'A' ). apply (np.mean)
Out[ 25 ]:
B C
A
a 2.000000 100.333333
b 5.500000 91.500000
c 4.333333 124.000000
|
5、将某列数据按数据值分成不同范围段进行分组运算
创建数据集:
1
2
3
4
5
6
7
8
9
10
11
|
np.random.seed( 0 )
df = pd.DataFrame({ 'Age' : np.random.randint( 20 , 70 , 100 ),
'Sex' : np.random.choice([ 'Male' , 'Female' ], 100 ),
'number_of_foo' : np.random.randint( 1 , 20 , 100 )})
Out[ 38 ]:
Age Sex number_of_foo
0 64 Female 14
1 67 Female 14
2 20 Female 12
3 23 Male 17
4 23 Female 15
|
目标:将age字段分成三组,有如下两种方法实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
#第一种方法:
1 、bins = 4
pd.cut(df[ 'Age' ], bins = 4 )
0 ( 56.75 , 69.0 ]
1 ( 56.75 , 69.0 ]
2 ( 19.951 , 32.25 ]
3 ( 19.951 , 32.25 ]
4 ( 19.951 , 32.25 ]...
#第二种方法
2 、bins = [ 19 , 40 , 65 , np.inf]
pd.cut(df[ 'Age' ], bins = [ 19 , 40 , 65 ,np.inf])
Out[ 40 ]:
0 ( 40.0 , 65.0 ]
1 ( 65.0 , inf]
2 ( 19.0 , 40.0 ]
3 ( 19.0 , 40.0 ]
4 ( 19.0 , 40.0 ]
#分组范围结果如下:
age_groups = pd.cut(df[ 'Age' ], bins = [ 19 , 40 , 65 ,np.inf])
df.groupby(age_groups).mean()
Out[ 43 ]:
Age number_of_foo
Age
( 19.0 , 40.0 ] 29.840000 9.880000
( 40.0 , 65.0 ] 52.833333 9.452381
( 65.0 , inf] 67.375000 9.250000
#按‘Age'分组范围和性别(sex)进行制作交叉表
pd.crosstab(age_groups, df[ 'Sex' ])
Out[ 44 ]:
Sex Female Male
Age
( 19.0 , 40.0 ] 22 28
( 40.0 , 65.0 ] 18 24
( 65.0 , inf] 3 5
|
agg:
1、使用groupby按照某列(A)进行分组后,需要对另外一列采用不同的聚合方法:
1
2
3
4
5
6
7
8
|
df.groupby( 'A' )[ 'B' ].agg({ 'mean' :np.mean, 'std' : np.std})
Out[ 16 ]:
std mean
A
a 1.00000 2.000000
b 2.12132 5.500000
c 3.21455 4.333333
|
2、按照某列进行分组后,对不同的列采用不同的聚合方法:
1
2
3
4
5
6
7
8
9
|
df.groupby( 'A' ).agg({ 'B' :[np.mean, 'sum' ], 'C' :[ 'count' ,np.std]}) #[]中对应的是两种方法
Out[ 17 ]:
C B
count std mean sum
A
a 3 4.509250 2.000000 6
b 2 6.363961 5.500000 11
c 3 34.394767 4.333333 13
|
transform:
前面两种方法得到的结果是以A列值为索引的结果,如果使用没有进行groupby分组的index的话,该怎么操作呢?此时就要用到transform函数了。transform(func, args, *kwargs) 方法简化了这个过程,: func 参数应用到所有分组,然后把结果放置到原数组的 index 上:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
df
Out[ 31 ]:
A B C
0 a 2 100
1 b 7 87
2 a 1 96
3 c 3 130
4 a 3 105
5 c 2 87
6 b 4 96
7 c 8 155
df.groupby( 'A' )[ 'B' , 'C' ].transform( 'count' ) #注:count函数在计算时,不计算nan值
Out[ 32 ]:
B C
0 3 3
1 2 2
2 3 3
3 3 3
4 3 3
5 3 3
6 2 2
7 3 3
|
从中可以看出:按A列进行分组,对B、C两列进行计数时,B为a的索引有[0,2,4],所以结果列的中[0,2,4]索引的值都为3,相当于广播了。对于C列,同理。
到此这篇关于python中分组函数groupby和分组运算函数agg的使用的文章就介绍到这了,更多相关python 分组函数groupby和分组运算函数agg内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!
原文链接:https://blog.csdn.net/weixin_37536446/article/details/82109431