python组函数_python笔记 - 分组相关函数

这篇笔记主要是关于pandas中三个函数groupby()、crosstab()、pivot_table(),平常做数据统计表时会经常使用。

一、groupby()

基本使用

# 对一列进行分组

df['data1'].groupby(df['key1’]).mean() # 结果是series

df[['data1','data2']].groupby(df['key1']).sum() # 结果是dataframe

df.groupby('key1’)['data1'].mean() # 结果是series

# 设置参数as_index=False,可避免分组键组成索引,如果结果列是单列,要写成df.groupby才能使用as_index

df.groupby('key1',as_index = False)['data1'].sum() # 图2 结果是dataframe形式

df.groupby('key1’)[['data1','data2']].mean() # 结果是dataframe形式

# 默认所有数值列都要被聚合

df.groupby('key1').mean()

# 对两列进行分组,出来的结果,索引是具有层次化的两列

means = df['data1'].groupby([df['key1'], df['key2']]).mean() #结果是series

means.unstack() #把内层的索引抽出来成为列,结果是DataFrame

# 多列分组多列结果

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

# 返回分组大小

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

# 聚合函数使用自定义函数

df.groupby('key1').agg(lambda x: x.max()-x.min())

--------------------------

# 自定义分组

key = list('ototo') # 要和行的数量一致

df.groupby(key).mean()

# 结果

data1 data2

o -0.211108 0.162019

t -0.354277 -0.845506

--------------------------

# 使用describe()

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

count mean std min 25% 50% 75% \

key1

a 4.0 0.263429 0.948813 -0.786293 -0.160546 0.165381 0.589355

b 4.0 0.464058 1.447415 -1.146518 -0.137997 0.318070 0.920126

c 3.0 -0.444718 0.527141 -1.053396 -0.598537 -0.143678 -0.140379

max

key1

a 1.509245

b 2.366611

c -0.137080

# 转置

df.groupby('key1')['data1'].describe().T

key1 a b c

count 4.000000 4.000000 3.000000

mean 0.263429 0.464058 -0.444718

std 0.948813 1.447415 0.527141

min -0.786293 -1.146518 -1.053396

25% -0.160546 -0.137997 -0.598537

50% 0.165381 0.318070 -0.143678

75% 0.589355 0.920126 -0.140379

max 1.509245 2.366611 -0.137080

分组使用不同聚合函数

# 多列使用多个一样的聚合函数

df.groupby(['key1'])[['data1','data2']].agg(['count', 'mean', 'max'])

# 多列对应多个聚合函数,不同列对应不同的聚合函数

df.groupby(['key1'])[['data1','data2']].agg({'data1':'sum','data2':'mean'})

# 显示分组结果时,给聚合函数取别名

ftuples = [('平均数', 'mean'),('总和', 'sum')] #注意是元组的形式

df.groupby(['key1'])[['data1','data2']].agg(ftuples)

结合transform使用

注意:使用transform返回的数据大小和原始的df大小一样(行列)

df

# 结果

key1 key2 data1 data2

0 a one 0.112262 -0.993748

1 a two -0.449957 -0.580374

2 b one 0.560749 -0.202874

3 b two -0.258597 -1.110639

4 a one -1.306336 1.682677

----------------

df.groupby('key1').mean()

# 结果

data1 data2

key1

a -0.548010 0.036185

b 0.151076 -0.656756

----------------

# groupby结合transform使用

df.groupby('key1').transform(np.mean)

# 结果 和原始的df行数相同,并生成的是对应的组的均值

data1 data2

0 -0.548010 0.036185

1 -0.548010 0.036185

2 0.151076 -0.656756

3 0.151076 -0.656756

4 -0.548010 0.036185

# 和group合并,实现在原表基础上添加列存放所属组均值的列,也可以使用df和普通的groupby做merge实现

pd.concat([df,meanData], axis = 1)

#结果

key1 key2 data1 data2 data1 data2

0 a one 0.112262 -0.993748 -0.548010 0.036185

1 a two -0.449957 -0.580374 -0.548010 0.036185

2 b one 0.560749 -0.202874 0.151076 -0.656756

3 b two -0.258597 -1.110639 0.151076 -0.656756

4 a one -1.306336 1.682677 -0.548010 0.036185

4、结合apply使用

​ 将待处理对象拆分为多个对象-->对每一个对象应用函数-->最后合并数据

​ 每个组的大小,取决于apply中的函数返回,可以返回多值。(区别于groupby中默认使用聚合函数)

df

#

key1 key2 data1 data2

0 a one 0.282725 -0.961001

1 a two -0.786293 1.067054

2 b one 0.437965 -0.470522

3 b two 0.198176 2.503218

4 a one 1.509245 0.714996

5 a one 0.048036 -0.058840

6 b two -1.146518 -1.049952

7 c one -0.143678 -1.182260

8 c two -1.053396 -0.301872

9 b one 2.366611 0.419086

10 c one -0.137080 -0.914790

---------------

# 取每组按某列排最大的n个

def top(df,n=3,column = 'data1'):

return df.sort_values(by = column)[-n:]

df.groupby('key1').apply(top,n=2)

#

key1 key2 data1 data2

key1

a 0 a one 0.282725 -0.961001

4 a one 1.509245 0.714996

b 2 b one 0.437965 -0.470522

9 b one 2.366611 0.419086

c 7 c one -0.143678 -1.182260

10 c one -0.137080 -0.914790

二、pivot_table()

1.定义:

DataFrame.pivot_table(values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, dropna=True, margins_name='All')

2.参数:

values: 可选参数,用来做集合的值,默认是显示所有的值。

index:必选参数,用来指定行索引。如果用数组做行索引,数据必须等长。

columns:必选参数,用来指定列索引。

aggfunc:聚合函数,默认是 np.mean , 支持numpy 的计算方法

fill_value:填充NA值。默认不填充

margins:添加行列的总计,默认不显示。

dropna:如果整行都为NA值,则进行丢弃,默认丢弃。

margins_name:在margins参数为ture时,用来修改margins的名称

3.使用

tips.head(10)

total_bill tip sex smoker day time size tip_pct

0 16.99 1.01 Female No Sun Dinner 2 0.059447

1 10.34 1.66 Male No Sun Dinner 3 0.160542

2 21.01 3.50 Male No Sun Dinner 3 0.166587

3 23.68 3.31 Male No Sun Dinner 2 0.139780

4 24.59 3.61 Female No Sun Dinner 4 0.146808

5 25.29 4.71 Male No Sun Dinner 4 0.186240

6 8.77 2.00 Male No Sun Dinner 2 0.228050

7 26.88 3.12 Male No Sun Dinner 4 0.116071

8 15.04 1.96 Male No Sun Dinner 2 0.130319

9 14.78 3.23 Male No Sun Dinner 2 0.218539

------------------------

# 1.普通透视表,设定index

tips.pivot_table(index=['sex','smoker'])

# 结果

size tip tip_pct total_bill

sex smoker

Female No 2.592593 2.773519 0.156921 18.105185

Yes 2.242424 2.931515 0.182150 17.977879

Male No 2.711340 3.113402 0.160669 19.791237

Yes 2.500000 3.051167 0.152771 22.284500

------------------------

# 2.多层透视表

tips.pivot_table( values = ['tip_pct','size'], index = ['sex','day'],columns ='smoker')

# 结果

size tip_pct

smoker No Yes No Yes

sex day

Female Fri 2.500000 2.000000 0.165296 0.209129

Sat 2.307692 2.200000 0.147993 0.163817

Sun 3.071429 2.500000 0.165710 0.237075

Thur 2.480000 2.428571 0.155971 0.163073

Male Fri 2.000000 2.125000 0.138005 0.144730

Sat 2.656250 2.629630 0.162132 0.139067

Sun 2.883721 2.600000 0.158291 0.173964

Thur 2.500000 2.300000 0.165706 0.164417

------------------------

# 添加margins,多加一个ALL列,不考虑分组级别中的差异

tips.pivot_table( ['tip_pct','size'], index = ['sex','day'],columns ='smoker', margins = True)

# 结果

size tip_pct

smoker No Yes All No Yes All

sex day

Female Fri 2.500000 2.000000 2.111111 0.165296 0.209129 0.199388

Sat 2.307692 2.200000 2.250000 0.147993 0.163817 0.156470

Sun 3.071429 2.500000 2.944444 0.165710 0.237075 0.181569

Thur 2.480000 2.428571 2.468750 0.155971 0.163073 0.157525

Male Fri 2.000000 2.125000 2.100000 0.138005 0.144730 0.143385

Sat 2.656250 2.629630 2.644068 0.162132 0.139067 0.151577

Sun 2.883721 2.600000 2.810345 0.158291 0.173964 0.162344

Thur 2.500000 2.300000 2.433333 0.165706 0.164417 0.165276

All 2.668874 2.408602 2.569672 0.159328 0.163196 0.160803

-------------------------

# 添加fill_value,aggfunc

tips.pivot_table('size',index=['time','sex','smoker'],columns='day',aggfunc='sum', fill_value=0)

# 结果

day Fri Sat Sun Thur

time sex smoker

Dinner Female No 2 30 43 2

Yes 8 33 10 0

Male No 4 85 124 0

Yes 12 71 39 0

Lunch Female No 3 0 0 60

Yes 6 0 0 17

Male No 0 0 0 50

Yes 5 0 0 23

三、crosstab()

交叉表,计算分组频率的特殊透视表,相当于pivot_table()中aggfunc参数默认为count

In [21]: data

Out[21]:

Sample Gender Handedness

0 1 Female Right-handed

1 2 Male Left-handed

2 3 Female Right-handed

3 4 Male Right-handed

4 5 Male Left-handed

5 6 Male Right-handed

6 7 Female Right-handed

7 8 Female Left-handed

8 9 Male Right-handed

9 10 Female Right-handed

# 简单交叉表实现,只接收两个参数时,将提供一个频率表。

In [22]: pd.crosstab(data['Gender'],data['Handedness'])

Out[22]:

Handedness Left-handed Right-handed

Gender

Female 1 4

Male 2 3

# 添加margins

In [23]: pd.crosstab(data.Gender,data.Handedness, margins=True)

Out[23]:

Handedness Left-handed Right-handed All

Gender

Female 1 4 5

Male 2 3 5

All 3 7 10

# 添加normalize,设置百分比

pd.crosstab(nf['A'],nf['B'],normalize=True)

# 其他还有些参数和pivot_table()使用方法差不多。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值