pandas 的分组与聚合运算/groupby/transform/apply/agg

dataframe.groupby():

用途:对一个dataframe或series进行分组计算操作
基本语法: DataFrame.groupby(by=None, axis=0, level=None, as_index=True, sort=True, group_keys=True, squeeze=False, **kwargs)
参数释义:
by : 计算方式
by=函数:对df/series的每一个数据进行函数操作
by=字典/series
axis=0,1,columns,index, 0/index表示对行进行操作,1/columns表示对列,默认0
level=int/level 名称(列表):用于多层dataframe指定索引层
as_index:返回值是否使用原索引
sort: bool, 默认true,对分组结果的key进行排序,但不改变分组内部值的顺序
group_keys:与apply函数配合使用,以传入分组的键名
squeeze :如果返回值是多维的,则压缩维度,默认False

groupby生成的是groupby对象,无法直接进行计算,需要调用其他计算方法

import pandas as pd
import numpy as np
import pandas as pd
import numpy as np
df = pd.DataFrame([('bird', 'Falconiformes', 389.0),
                    ('bird', 'Psittaciformes', 24.0),
                    ('mammal', 'Carnivora', 80.2),
                    ('mammal', 'Primates', np.nan),
                    ('mammal', 'Carnivora', 58)],
                   index=['falcon', 'parrot', 'lion', 'monkey', 'leopard'],
                   columns=('class', 'order', 'max_speed'))
grouped1=df.groupby('class')#by传入列/行名
grouped2 = df.groupby('order', axis='columns') #指定轴
grouped3 = df.groupby(['class', 'order'])#by传入列/行列表

#by传入函数名
def upper(value):
    if value.startswith('m'):
        return value.upper()

grouped4 = df.groupby(upper,axis=1)

#by传入字典:
mapping={'bird':'鸟','mammal':'哺乳'}
grouped5 = df.groupby(mapping)#by传入函数名

print(type(grouped1))
#输出:
<class 'pandas.core.groupby.groupby.DataFrameGroupBy'>

groupby对象的方法:

groupby.groups:
直接查看分组结果,返回字典:

df = pd.DataFrame({'X': ['B', 'B', 'A', 'A'], 'Y': [1, 2, 2, 4]})
grouped=df.groupby('X').groups
print(grouped)
#输出:
{'A': Int64Index([2, 3], dtype='int64'), 'B': Int64Index([0, 1], dtype='int64')}
#返回的字典的value是他们在原df中索引号的列表

groupby的聚合函数:
在这里插入图片描述

df2 = pd.DataFrame({'X': ['B', 'B', 'A', 'A'], 'Y': [1, 2, 2, 4]})

print(df2)
print('sum',df2.groupby(['X']).sum())
print('mean',df2.groupby(['X']).mean())
print('size',df2.groupby(['X']).size())
print('count',df2.groupby(['X']).count())
print('var',df2.groupby(['X']).var())
print('describe',df2.groupby(['X']).describe())
print('first',df2.groupby(['X']).first())
print('last',df2.groupby(['X']).last())
print('min',df2.groupby(['X']).min())
print('max',df2.groupby(['X']).max())
#输出:
   X  Y
0  B  1
1  B  2
2  A  2
3  A  4
sum    
		Y
X   
A  6
B  3

mean     
	 Y
X     
A  3.0
B  1.5

size X
A    2
B    2
dtype: int64

count    
	Y
X   
A  2
B  2

var     
	 Y
X     
A  2.0
B  0.5
describe      
			 Y                                          
  count  mean std  min   25%  50%   75%  max
X                                                
A   2.0  3.0  1.414214  2.0  2.50  3.0  3.50  4.0
B   2.0  1.5  0.707107  1.0  1.25  1.5  1.75  2.0

# 25%指最小四分位数,75%指最大四分位数,50%指中位数

first    
	Y
X   
A  2
B  1

last    
	Y
X   
A  4
B  2

min    
	Y
X   
A  2
B  1

max   
	 Y
X   
A  4
B  2

groupby.agg():同时运用一个或多个groupby 函数
语法:DataFrame.agg(func, axis=0, *args, **kwargs)

func : 函数,函数名称,函数列表,字典{‘行名/列名’,‘函数名’}
axis=0:0/index 作用于列 1/columns作用于行

import pandas as pd
import numpy as np
from pandas import DataFrame
import numpy as np
np.random.seed(2764)
df=DataFrame({'M':list('ABCBA'),'N':list('XYZXY'),'J':[1,4,6,7,2],'K':[5,3,3,2,6]})
grouped=df.groupby(['M','N']).agg(['mean','max'])
print(grouped)
#输出:
       J        K    
    mean max mean max
M N                  
A X    1   1    5   5
  Y    2   2    6   6
B X    7   7    2   2
  Y    4   4    3   3
C Z    6   6    3   3

groupby以后指定某列进行计算:

grouped=df.groupby(['M','N']).K.agg(['mean','max'])
#输出:
     mean  max
M N           
A X     5    5
  Y     6    6
B X     2    2
  Y     3    3
C Z     3    3

GroupBy.apply(func, *args, **kwargs):对了df/series运用已有函数/自定义函数
func:函数名,func的第一个参数必须是作用的dataframe
args:func的参数

np.random.seed(2764)
df=DataFrame({'M':list('ABCBA'),'N':list('XYZXY'),'J':[1,4,6,7,2],'K':[5,3,3,2,6]})

def func(df):
    return df['J']-df['K']

grouped=df.groupby(df['M']).apply(func)
print(grouped)
#输出:
M   
A  0   -4
   4   -4
B  1    1
   3    5
C  2    3
dtype: int64

DataFrame.transform(func, axis=0, *args, **kwargs)
对groupby后的dataframe中的每个数据进行func运算,返回运算后的dataframe

np.random.seed(2764)
df=DataFrame({'M':list('ABCBA'),'N':list('XYZXY'),'J':[1,4,6,7,2],'K':[5,3,3,2,6]})
#输出:
    N   J   K
0  XY   3  11
1  YX  11   5
2   Z   6   3
3  YX  11   5
4  XY   3  11

apply和transform的区别
apply:func是一个函数,传入的参数可以是该dataframe的多个series,可以指定这些series进行相互运算。返回的结果类型是函数中return的类型

transform: func可以是函数,函数列表或字典{‘轴名称’,函数名称}(即对指定轴使用指定函数)。transform是对dataframe的每个值进行func运算,dataframe被的各series之间不可运算,返回的值结构与被作用的dataframe结构相同。

transform能用的func,apply一定能用。反之,apply 能用的函数,transform不一定能用

如何理解:

np.random.seed(2764)
df=DataFrame({'M':list('ABCBA'),'N':list('XYZXY'),'J':[1,4,6,7,2],'K':[5,3,3,2,6]})

#func是对dataframe 内的列进行运算,比如列的加减等等
#def func(df):
   # return df['J']-df['K']

#transform的func2传入的参数x指的是dataframe的每个值,值对每个值进行运算
def func2(x):
    return x.sum()

grouped=df.groupby(df['M']).apply(func2)
print(grouped)

grouped2=df.groupby(df['M']).transform(func2)
print(grouped2)
#输出:
    M   N   J   K
M                
A  AA  XY   3  11
B  BB  YX  11   5
C   C   Z   6   3

    N   J   K
0  XY   3  11
1  YX  11   5
2   Z   6   3
3  YX  11   5
4  XY   3  11
**#apply可以传入func或func2,但transform只能传入func2**

dataframe.apply文档链接:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.apply.html

dataframe.transform 文档:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.transform.html

dataframe.agg 文档:https://pandas.pydata.org/pandas-docs/version/0.23.3/generated/pandas.DataFrame.agg.html

猜你喜欢

转载自blog.csdn.net/weixin_44595372/article/details/88285508
今日推荐