文章目录
import numpy as np
import pandas as pd
groupby对象
df1 = pd.DataFrame({'key':['A','B','C','A','B','C'],'data':range(6)},columns=['key','data'])
df1.groupby('key').sum()
# 将所有的列都进行求和,所以生成的是DataFrame
按列取值
df1.groupby('key')['data'].sum()
df1.groupby('key')['data'].describe()
# 可以直接调用方法
groupby对象可以按组迭代
for (m,g) in df1.groupby('key'):
print(m,g)
累计、过滤、转换和应用
rng = np.random.RandomState(0)
df = pd.DataFrame({'key':['A','B','C','A','B','C'],
'data1':range(6),
'data2':rng.randint(0,10,6)},
columns=['key','data1','data2'])
累计
df.groupby('key').aggregate(['min',np.median,max])
# aggregate函数中可以指定多个统计方法,用列表传入进去
df.groupby('key').aggregate({'data1':sum,'data2':'max'})
# 也可以指定不同列,不同的统计方法,将一个列名为键,统计方法为值的字典传入进去
过滤
# 可以编写一个过滤函数,或者写一个lambda表达式用于过滤
# 传入的参数是每一组的数据
def filter_func(x):
return x['data2'].std()>4
f = lambda x:x['data2'].std()>4
# 分组之后,组内data2值的标准差要大于4
print(df);print(df.groupby('key').std())
df.groupby('key').filter(f)
# 返回一个过滤后的DataFrame
转换
df.groupby('key').transform(lambda x:x-x.mean())
apply方法
def norm(x):
x['data1'] /= x['data2'].sum()
return x
df.groupby('key').apply(norm)
转换transform方法,和apply方法类似,transform是将所有的列都带入指定的方法处理,apply而是将整个DataFrame带入,处理指定的列
df.groupby('key').apply(lambda x:x-x.mean())
df.groupby('key').transform(lambda x:x-x.mean())
# 结果相同
apply和filter中传入的方法的区别
apply中的方法,输入的是分组数据的DataFrame,返回的是pandas对象或者标量,用于替换/添加数据
filter中的方法,输入的是分组数据的DataFrame,返回的是一个布尔类型的数据,用于过滤数据
设置分割的键
上面的分组都是以一列进行分割的,groupby
还支持多种分组方式
将列表、数组、Series或者索引作为分组键
# 根据指定列表进行分组
l = [0,1,0,1,2,0]
print(df)
df.groupby(l).aggregate([sum,np.std])
# 指定Series来进行分组
df.groupby(df.key).sum()
用字典或Series将索引映射到索引名称
df=df.set_index('key')
mapp = {'A':'V','B':'Y','C':'Y'}
df.groupby(mapp).aggregate(sum)
# 默认是根据索引传进去进行分组
任意的python函数
df.groupby(str.lower).sum()
# 默认是根据索引传进去进行分组
多个有效键构成的列表
df.groupby([str.lower,l]).sum()
# 按照索引的小写,和l列表进行分组