pandas如何按日期分组分别统计分类列的各分类计数
按日期分性别统计人数的实现方案
需求说明
现有数据表包含两列:
Gender:人员性别,值为M/FLastStart:人员开始日期
需要按日期维度聚合,统计每个日期下男、女的人员数量,原始样例数据如下:
| Gender | LastStart |
|---|---|
| M | 2013-05-21 |
| M | 2013-05-24 |
| F | 2013-05-27 |
| M | 2013-05-27 |
| F | 2013-05-28 |
| F | 2013-05-28 |
预期输出格式:
| LastStart | M | F |
|---|---|---|
| 2013-05-21 | 1 | 0 |
| 2013-05-24 | 1 | 0 |
| 2013-05-27 | 1 | 1 |
| 2013-05-28 | 0 | 2 |
之前尝试多列groupby后调用pivot失败,因为groupby聚合后返回的是Series类型,没有pivot方法。
可行实现方法
方法1:直接用crosstab一步生成(最简便)
pd.crosstab是pandas专门用于生成分组频数表的函数,不需要额外做聚合、转置操作,直接传入行、列维度即可,自动补全缺失分类的计数为0:
import pandas as pd # 构造/读取原始数据 df = pd.DataFrame({ 'Gender': ['M','M','F','M','F','F'], 'LastStart': ['2013-05-21','2013-05-24','2013-05-27','2013-05-27','2013-05-28','2013-05-28'] }) # 建议先把LastStart转为日期类型,避免字符串排序/格式问题 df['LastStart'] = pd.to_datetime(df['LastStart']).dt.date # 直接生成统计结果 result = pd.crosstab(index=df['LastStart'], columns=df['Gender'])
运行后result的输出和预期完全一致。
方法2:groupby聚合后用unstack转置(适配原有思路)
多列groupby计数后返回的是多层索引的Series,不需要转成DataFrame再pivot,直接调用unstack把性别维度的行索引转成列即可,通过fill_value=0把无记录的性别计数填充为0:
result = df.groupby(['LastStart', 'Gender']).size().unstack(fill_value=0)
注意:这里聚合要用size()而不是count(),count()会排除空值,size()统计所有分组的记录数,更符合计数需求。
内容的提问来源于stack exchange,提问作者Luke
相关产品推荐
相关产品推荐

