目录
1.单类分组
A.groupby('性别')
首先,我们有一个变量A,数据类型是DataFrame,想要按照【性别】进行分组,得到的结果是一个Groupby对象,还没有进行任何的运算。
describe()
描述组内数据的基本统计量
A.groupby("性别").describe().unstack()
-
只有数字类型的列数据才会计算统计
-
示例里面数字类型的数据有两列 【班级】和【身高】
但是,我们并不需要统计班级的均值等信息,只需要【身高】,所以做一下小的改动:
A.groupby("性别")["身高"].describe().unstack()
unstack() 索引重排
2.多类分组
A.groupby( [“班级”,“性别”])
单独用groupby,我们得到的还是一个 Groupby 对象。
mean() 组内均值计算
DataFrame的很多函数可以直接运用到Groupby对象上。
A.groupby( ["班级","性别"]).agg([np.sum, np.mean, np.std]) # 一次计算了三个
我们还可以一次运用多个函数计算
agg() 分组多个运算
# 对sales进行操作,按4列进行分组,并求 [ 'item_id' ]列的频数
group = sales.groupby(['state_id', 'store_id', 'cat_id', 'dept_id'], as_index=False)['item_id'].count()
as_index=False,保持原来的数据索引结果不变,表示分组的四列[‘state_id’, ‘store_id’, ‘cat_id’, ‘dept_id’]不做索引,而是作为dataframe的列输出。
对于数据的分组和分组运算主要是指groupby函数的应用,具体函数的规则如下:
df.groupby([df[属性],df[属性]) (指分类的属性,数据的限定定语,可以有多个 ).mean()(对于数据的计算方式——函数名称)
分组计算后重命名
对分组计算进行for循环
分组后调用自定义函数
# 聚合后重命名,ak_dict是'filled_ntf'列经过CapacityAys.weibull_para计算后的结果
# 'filled_ntf_mean'是'filled_ntf'列经过mean()计算后的结果
ws_ym_mean_ak = temp.groupby(by=['year', 'month'], as_index=False)\
.agg(ak_dict=('filled_ntf', CapacityAys.weibull_para), filled_ntf_mean=('filled_ntf', 'mean'))
for date, df in temp0.groupby(['year', 'month']): # date=('year', 'month')
date # 'year', month数据,通过date[0]和date[1]获取
df#分组后的数据
# as_index=True 就是要把['year', 'month']合并起来作为索引,调用自定义类函数CapacityAys().weibull_para
ak_value = temp.groupby(['year', 'month'], as_index=True)['filled_风速_mean_ntf'].agg(CapacityAys().weibull_para)
3.时间分组
时间序列可以直接作为index,或者有一列是时间序列,差别不是很大。 这里仅仅演示,某一列为时间序列。
为 A 新增一列【生日】,由于分隔符 “/” 的问题,我们查看列属性,【生日】的属性并不是日期类型
(1) 按照【生日】的【年份】进行分组,看看有多少人是同龄?
A["生日"] = pd.to_datetime(A["生日"],format ="%Y/%m/%d") # 转化为时间格式
A.groupby(A["生日"].apply(lambda x:x.year)).count() # 按照【生日】的【年份】分组
(2) 同一年作为一个小组,小组内生日靠前的那一位作为小队长:
A.sort_values("生日", inplace=True) # 按时间排序
A.groupby(A["生日"].apply(lambda x:x.year),as_index=False).first()
as_index=False # 保持原来的数据索引结果不变
first() 保留第一个数据
Tail(n=1) 保留最后n个数据
再进一步:
(3) 想要找到哪个月只有一个人过生日
A.groupby(A["生日"].apply(lambda x:x.month),as_index=False) # 到这里是按月分组
A.groupby(A["生日"].apply(lambda x:x.month),as_index=False).filter(lambda x: len(x)==1)
- filter() 对分组进行过滤,保留满足()条件的分组
- 用 first(),tail()截取每组前后几个数据
- 用 apply()对每组进行(自定义)函数运算
- 用 filter()选取满足特定条件的分组
4. groupby之后对不同列运用聚合函数
4.1 方法1
这种方法会导致多级索引
df.groupby('group').agg({'a':['sum', 'max'],
'b':'mean',
'c':'sum',
'd': lambda x: x.max() - x.min()})
a b c d
sum max mean sum <lambda>
group
0 0.864569 0.446069 0.466054 0.969921 0.341399
1 1.478872 0.843026 0.687672 1.754877 0.672401
4.2 方法2
def f(x):
d = {}
d['a_sum'] = x['a'].sum()
d['a_max'] = x['a'].max()
d['b_mean'] = x['b'].mean()
d['c_d_prodsum'] = (x['c'] * x['d']).sum()
return pd.Series(d, index=['a_sum', 'a_max', 'b_mean', 'c_d_prodsum'])
df.groupby('group').apply(f)
a_sum a_max b_mean c_d_prodsum
group
0 0.864569 0.446069 0.466054 0.173711
1 1.478872 0.843026 0.687672 0.630494
这种方法很好。在groupby之后的每个子DF,可以运用聚合函数;
这里自己构建完成的Series
列索引是平铺的,比较直观;
** 也可以这样简写:**
df.groupby('group') \
.apply(lambda x: pd.Series({
'a_sum' : x['a'].sum(),
'a_max' : x['a'].max(),
'b_mean' : x['b'].mean(),
'c_d_prodsum' : (x['c'] * x['d']).sum()
})
)
a_sum a_max b_mean c_d_prodsum
group
0 0.530559 0.374540 0.553354 0.488525
1 1.433558 0.832443 0.460206 0.053313
4.3 方法3
In [26]: f = {'A':['sum','mean'], 'B':['prod']}
In [27]: df.groupby('GRP').agg(f)
Out[27]:
A B
sum mean prod
GRP
0 0.719580 0.359790 0.102004
1 0.454824 0.227412 0.034060
这其实是一种变形,把agg变成一个map单独传入
结果对于列来说,仍然是二级索引;
4.4 方法4
df.groupby('group').agg(
a_sum=('a', 'sum'),
a_mean=('a', 'mean'),
b_mean=('b', 'mean'),
c_sum=('c', 'sum'),
d_range=('d', lambda x: x.max() - x.min())
)
a_sum a_mean b_mean c_sum d_range
group
0 0.947337 0.473668 0.871939 0.838150 0.320543
1 0.604149 0.302074 0.656902 0.542985 0.057681
这种方法更加直观,我比较喜欢;
有个变种可以这样写:
4.5 最后,回顾一下单个列的写法
In [84]: animals.groupby("kind").height.agg(
....: min_height='min',
....: max_height='max',
....: )
....:
Out[84]:
min_height max_height
kind
cat 9.1 9.5
dog 6.0 34.0
或者这样:
# 聚合单列
grouped_single = df.groupby('Team').agg({'Age': ['mean', 'min', 'max']})
grouped_single.columns = ['age_mean', 'age_min', 'age_max']
grouped_single = grouped_single.reset_index()
# 聚合多列
grouped_multiple = df.groupby(['Team', 'Pos']).agg({'Age': ['mean', 'min', 'max']})
grouped_multiple.columns = ['age_mean', 'age_min', 'age_max']
grouped_multiple = grouped_multiple.reset_index()
5. 其它应用案例
data_all_profile.groupby('is_turn').size()
Out[3]:
is_turn
0 6470
1 38194
3 78764
dtype: int64
data_all_profile.groupby('is_turn').size().reset_index(name='count')
Out[4]:
is_turn count
0 0 6470
1 1 38194
2 3 78764
参考链接:
[1]链接1 ;