0

0

Pandas数据框:高效汇总月度数据至季度与年度

碧海醫心

碧海醫心

发布时间:2025-09-23 14:35:57

|

881人浏览过

|

来源于php中文网

原创

pandas数据框:高效汇总月度数据至季度与年度

本文将详细介绍如何使用Pandas高效地将数据框中以YYYYMM格式表示的月度列数据,按行汇总为季度和年度数据。核心策略包括将宽格式数据转换为长格式(melt操作),从时间列中提取年份、月份和季度信息,然后利用groupby功能进行灵活的数据聚合,最终生成季度和年度汇总结果。

引言:处理宽格式时间序列数据

在数据分析实践中,我们经常会遇到以“宽格式”存储的时间序列数据,其中每个时间点(例如月份)对应一个独立的列。这种格式在展示时直观,但在进行跨时间维度(如季度、年度)的聚合计算时却显得笨拙。传统方法可能需要手动指定每个季度或年度包含的列名,这不仅效率低下,且难以适应动态的时间范围。本文将提供一种基于Pandas的通用解决方案,通过数据重塑和时间维度提取,实现对月度数据的自动化季度和年度汇总。

数据准备与问题概述

假设我们有一个Pandas DataFrame,其中包含多个实体(如产品A、B)在不同月份的数值数据。月份列的命名遵循YYYYMM格式。

示例数据:

import pandas as pd

data = {
    '201003': [10, 14],
    '201004': [11, 19],
    '201005': [14, 20],
    '201006': [22, 22],
    '201007': [10, 26],
    '201008': [19, 11],
    '201101': [5, 8],
    '201102': [7, 12],
    '201103': [9, 15]
}
df_original = pd.DataFrame(data, index=['A', 'B'])

print("原始DataFrame:")
print(df_original)

输出:

原始DataFrame:
   201003  201004  201005  201006  201007  201008  201101  201102  201103
A      10      11      14      22      10      19       5       7       9
B      14      19      20      22      26      11       8      12      15

我们的目标是:

  1. 将每个实体(A、B)的月度数据汇总为季度数据(例如2010年第二季度、2010年第三季度)。
  2. 将每个实体(A、B)的月度数据汇总为年度数据(例如2010年、2011年)。 并且,这个过程应该是动态的,无需手动指定具体的月份列。

核心策略:从宽到长的转换 (melt)

处理宽格式时间序列数据的关键一步是将其转换为“长格式”。Pandas的melt()函数是实现这一转换的强大工具。它将指定的列(这里是所有的月份列)“融化”成两列:一列包含原始列名(即YYYYMM),另一列包含对应的值。为了保留原始的行标识符('A'和'B'),我们需要先将其转换为一个常规列,再作为id_vars参数传递给melt()。

# 将索引转换为常规列,以便在melt操作中保留
df_melted = df_original.reset_index().rename(columns={'index': 'ID'})

# 使用melt函数将月份列转换为行
# id_vars: 不进行融化的列,这里是我们的实体ID
# var_name: 新的变量列的名称,将包含原始的YYYYMM列名
# value_name: 新的值列的名称,将包含原始的数值
df_long = df_melted.melt(id_vars='ID', var_name='YYYYMM', value_name='Value')

print("\n转换后的长格式DataFrame:")
print(df_long.head())

输出:

转换后的长格式DataFrame:
  ID  YYYYMM  Value
0  A  201003     10
1  B  201003     14
2  A  201004     11
3  B  201004     19
4  A  201005     14

提取时间维度信息

在长格式数据中,所有的月份信息都集中在YYYYMM列。我们可以利用字符串切片操作,从中提取出年份和月份。

# 从YYYYMM列中提取年份
df_long['Year'] = df_long['YYYYMM'].str[:4]
# 从YYYYMM列中提取月份
df_long['Month'] = df_long['YYYYMM'].str[4:]

print("\n提取年份和月份后的DataFrame:")
print(df_long.head())

输出:

提取年份和月份后的DataFrame:
  ID  YYYYMM  Value  Year Month
0  A  201003     10  2010    03
1  B  201003     14  2010    03
2  A  201004     11  2010    04
3  B  201004     19  2010    04
4  A  201005     14  2010    05

计算季度信息

为了计算季度汇总,我们需要将月份映射到对应的季度。我们可以创建一个字典来定义这种映射关系,然后使用map()方法将其应用到Month列。

AI Time Machine
AI Time Machine

使用AI创建穿越历史的超逼真的头像

下载
# 定义月份到季度的映射
month_quarter_map = {
    '01': 1, '02': 1, '03': 1,  # Q1
    '04': 2, '05': 2, '06': 2,  # Q2
    '07': 3, '08': 3, '09': 3,  # Q3
    '10': 4, '11': 4, '12': 4   # Q4
}

# 应用映射创建Quarter列
df_long['Quarter'] = df_long['Month'].map(month_quarter_map)

print("\n添加季度信息后的DataFrame:")
print(df_long.head())

输出:

添加季度信息后的DataFrame:
  ID  YYYYMM  Value  Year Month  Quarter
0  A  201003     10  2010    03        1
1  B  201003     14  2010    03        1
2  A  201004     11  2010    04        2
3  B  201004     19  2010    04        2
4  A  201005     14  2010    05        2

执行季度和年度汇总

现在数据已经准备就绪,我们可以使用groupby()方法结合sum()进行汇总。

1. 季度汇总: 我们将按ID、Year和Quarter进行分组,然后对Value列求和。

df_quarterly_sums = df_long.groupby(['ID', 'Year', 'Quarter'])['Value'].sum().reset_index()

print("\n季度汇总结果:")
print(df_quarterly_sums)

输出:

季度汇总结果:
  ID  Year  Quarter  Value
0  A  2010        1     10
1  A  2010        2     47
2  A  2010        3     29
3  A  2011        1     21
4  B  2010        1     14
5  B  2010        2     61
6  B  2010        3     37
7  B  2011        1     35

如果希望将季度汇总结果转换为更接近原始宽格式的形态(例如,每个季度一个列),可以使用pivot_table或unstack:

df_quarterly_pivot = df_quarterly_sums.pivot_table(
    index=['ID', 'Year'],
    columns='Quarter',
    values='Value',
    fill_value=0 # 填充没有数据的季度为0
).add_prefix('Q').reset_index()

print("\n季度汇总结果(宽格式):")
print(df_quarterly_pivot)

输出:

季度汇总结果(宽格式):
  ID  Year  Q1  Q2  Q3
0  A  2010  10  47  29
1  A  2011  21   0   0
2  B  2010  14  61  37
3  B  2011  35   0   0

2. 年度汇总: 我们将按ID和Year进行分组,然后对Value列求和。

df_annual_sums = df_long.groupby(['ID', 'Year'])['Value'].sum().reset_index()

print("\n年度汇总结果:")
print(df_annual_sums)

输出:

年度汇总结果:
  ID  Year  Value
0  A  2010     86
1  A  2011     21
2  B  2010    112
3  B  2011     35

同样,年度汇总也可以转换为宽格式:

df_annual_pivot = df_annual_sums.pivot_table(
    index='ID',
    columns='Year',
    values='Value',
    fill_value=0
).add_prefix('Year_').reset_index()

print("\n年度汇总结果(宽格式):")
print(df_annual_pivot)

输出:

年度汇总结果(宽格式):
  ID  Year_2010  Year_2011
0  A         86         21
1  B        112         35

注意事项

  1. 索引处理: 在使用melt()之前,确保你的行标识符被正确地处理。如果你的DataFrame有命名索引,reset_index()是将其转换为常规列的有效方法。如果索引是默认的整数索引,且你不需要保留它作为聚合维度,则可以省略reset_index(),但要留意melt的默认行为。
  2. 数据类型: YYYYMM列在提取年份和月份后,它们将是字符串类型。在进行groupby操作时,字符串类型的Year和Quarter通常不会引起问题,但如果需要进行数值比较或计算,可能需要显式转换为整数类型(例如df_long['Year'].astype(int))。
  3. 性能考量: 对于非常大的DataFrame,melt操作可能会消耗较多的内存。如果数据量巨大,可以考虑分块处理或使用更内存高效的数据结构。
  4. 日期时间对象的优势: 虽然本教程使用了字符串切片和映射,但更健壮的方法是将YYYYMM列转换为Pandas的datetime对象。例如,pd.to_datetime(df_long['YYYYMM'], format='%Y%m')可以创建日期时间列,然后可以直接访问.dt.year, .dt.month, .dt.quarter等属性,这在处理更复杂的日期逻辑时会更加方便和安全。

总结

通过melt()、字符串操作和groupby()的组合使用,我们可以优雅且高效地将宽格式的月度数据汇总为季度和年度数据。这种方法避免了手动硬编码列名的繁琐,使得数据分析流程更加自动化和可扩展。掌握这种数据重塑和聚合技巧,对于处理时间序列数据的数据科学家和分析师来说至关重要。

相关专题

更多
Python 时间序列分析与预测
Python 时间序列分析与预测

本专题专注讲解 Python 在时间序列数据处理与预测建模中的实战技巧,涵盖时间索引处理、周期性与趋势分解、平稳性检测、ARIMA/SARIMA 模型构建、预测误差评估,以及基于实际业务场景的时间序列项目实操,帮助学习者掌握从数据预处理到模型预测的完整时序分析能力。

51

2025.12.04

数据类型有哪几种
数据类型有哪几种

数据类型有整型、浮点型、字符型、字符串型、布尔型、数组、结构体和枚举等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

299

2023.10.31

php数据类型
php数据类型

本专题整合了php数据类型相关内容,阅读专题下面的文章了解更多详细内容。

222

2025.10.31

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

617

2023.07.31

python中的format是什么意思
python中的format是什么意思

python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

430

2024.06.27

mysql标识符无效错误怎么解决
mysql标识符无效错误怎么解决

mysql标识符无效错误的解决办法:1、检查标识符是否被其他表或数据库使用;2、检查标识符是否包含特殊字符;3、使用引号包裹标识符;4、使用反引号包裹标识符;5、检查MySQL的配置文件等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

179

2023.12.04

Python标识符有哪些
Python标识符有哪些

Python标识符有变量标识符、函数标识符、类标识符、模块标识符、下划线开头的标识符、双下划线开头、双下划线结尾的标识符、整型标识符、浮点型标识符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

277

2024.02.23

java标识符合集
java标识符合集

本专题整合了java标识符相关内容,想了解更多详细内容,请阅读下面的文章。

252

2025.06.11

Java 项目构建与依赖管理(Maven / Gradle)
Java 项目构建与依赖管理(Maven / Gradle)

本专题系统讲解 Java 项目构建与依赖管理的完整体系,重点覆盖 Maven 与 Gradle 的核心概念、项目生命周期、依赖冲突解决、多模块项目管理、构建加速与版本发布规范。通过真实项目结构示例,帮助学习者掌握 从零搭建、维护到发布 Java 工程的标准化流程,提升在实际团队开发中的工程能力与协作效率。

10

2026.01.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 0.6万人学习

Rust 教程
Rust 教程

共28课时 | 4.3万人学习

Git 教程
Git 教程

共21课时 | 2.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号