如何动态使用Pandas datetime对象实现按年月统计观测值数量
Pandas 按年月维度聚合统计观测数实现方案
前置条件
现有仅含单列date的DataFrame,该列类型为datetime64[ns],存在重复日期值。目标是聚合生成包含两列的新DataFrame:第一列为标准YYYY-MM格式的年月标签,第二列为对应年月下的原始观测记录总数,匹配示例输出为2017-09 对应3条观测、2017-11对应2条观测的结果。
实操实现步骤
核心逻辑为:先从原datetime列提取可唯一标识「年+月」的维度值,再按该维度分组统计行数,最终整理为规整的DataFrame结构。
- 提取年月维度时,优先使用Pandas自带的
dt.to_period('M')接口,该方法生成的月级Period对象天生绑定年份信息,比单独提取dt.month字段更可靠 - 分组统计可复用通用的
groupby().size()方法,也可针对计数场景使用更简洁的value_counts()方法
注意:分组时必须确保维度携带年份信息,不要仅单独提取
dt.month字段做分组键,否则不同年份的相同月份(如2017-09和2018-09)会被合并统计,造成结果偏差。
参考代码
- 通用分组聚合写法(结果按时间维度升序排列,默认适合时序分析场景)
monthly_agg = df.groupby(df['date'].dt.to_period('M')).size()\ .reset_index(name='obs_count') # 若需要将年月标签转为标准"YYYY-MM"字符串格式,执行以下转换 monthly_agg['date'] = monthly_agg['date'].astype(str)
- 快速计数写法(适合只需要统计出现频次的场景)
monthly_agg = df['date'].dt.to_period('M').value_counts()\ .rename_axis('date').reset_index(name='obs_count') # 追加按时间排序逻辑,避免默认按计数降序打乱时间序列 monthly_agg = monthly_agg.sort_values('date').reset_index(drop=True) monthly_agg['date'] = monthly_agg['date'].astype(str)
最终输出验证
针对给定的示例数据集,上述代码运行后输出结果为:
| date | obs_count |
|---|---|
| 2017-09 | 3 |
| 2017-11 | 2 |
内容的提问来源于stack exchange,提问作者Clabis
相关产品推荐
相关产品推荐

