
在数据分析实践中,我们经常会遇到以“宽格式”存储的时间序列数据,其中每个时间点(例如月份)作为独立的列存在。例如,一个DataFrame可能包含多行实体(如产品、区域),而每个实体在不同月份的数值数据则分散在形如YYYYMM的列中。当需要对这些月度数据进行季度或年度层面的汇总分析时,直接对特定列进行硬编码求和会变得非常繁琐且难以维护,尤其当数据的时间范围动态变化时。
本教程将介绍一种灵活且强大的Pandas方法,通过数据重塑(melt)、字符串操作提取时间信息,以及groupby聚合,实现对这类月度数据的自动化季度和年度汇总。
首先,我们创建一个示例DataFrame来模拟原始的宽格式月度数据。为了能够对每行实体(如A、B)进行独立汇总,我们需要在melt操作中保留这些实体标识。
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
为了方便聚合,我们需要将这些表示月份的列转换成行。Pandas的melt函数是实现这一目标的关键。我们需要先将DataFrame的索引重置为普通列,然后指定哪些列作为标识符(id_vars),哪些列需要被“融化”(默认是除了id_vars之外的所有列)。
# 将索引重置为列,并进行melt操作
df_melted = df_original.reset_index().melt(
id_vars='index', # 指定'index'列作为标识符,不被融化
var_name='YYYYMM', # 新的变量列的名称,存储原列名(即YYYYMM)
value_name='Value' # 新的值列的名称,存储原列中的值
)
df_melted = df_melted.rename(columns={'index': 'ID'}) # 将'index'列重命名为'ID',更具可读性
print("\n融化后的DataFrame:")
print(df_melted.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
在融化后的DataFrame中,YYYYMM列包含了我们需要的所有时间信息。我们可以通过字符串切片轻松提取年份和月份,并进一步将月份映射到对应的季度。
# 从YYYYMM列中提取年份和月份
df_melted['Year'] = df_melted['YYYYMM'].str[:4]
df_melted['Month'] = df_melted['YYYYMM'].str[4:]
# 创建月份到季度的映射字典
month_quarter_map = {
'01': 1, '02': 1, '03': 1, # 第一季度
'04': 2, '05': 2, '06': 2, # 第二季度
'07': 3, '08': 3, '09': 3, # 第三季度
'10': 4, '11': 4, '12': 4 # 第四季度
}
# 使用map函数创建Quarter列
df_melted['Quarter'] = df_melted['Month'].map(month_quarter_map)
print("\n添加时间维度后的DataFrame:")
print(df_melted.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
有了ID、Year和Quarter列,我们现在可以轻松地按季度汇总数据。我们使用groupby函数指定聚合的维度,然后对Value列进行求和。
# 按ID、年份和季度汇总数据
quarterly_summary = df_melted.groupby(['ID', 'Year', 'Quarter'])['Value'].sum().reset_index()
print("\n按季度汇总结果:")
print(quarterly_summary)输出示例:
按季度汇总结果: 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
(注:示例数据中2010年Q1只有3月份数据,因此Value为10和14。2010年Q2包含4、5、6月,2010年Q3包含7、8月,2011年Q1包含1、2、3月。)
与季度汇总类似,年度汇总则更为简单,只需根据ID和Year进行分组求和。
# 按ID和年份汇总数据
annual_summary = df_melted.groupby(['ID', 'Year'])['Value'].sum().reset_index()
print("\n按年度汇总结果:")
print(annual_summary)输出示例:
按年度汇总结果: ID Year Value 0 A 2010 86 1 A 2011 21 2 B 2010 112 3 B 2011 35
如果用户希望将季度或年度汇总的结果也以宽格式(例如,每个季度或年份作为一列)呈现,可以使用pivot_table函数。
# 将季度汇总结果转换为宽格式
quarterly_wide_summary = quarterly_summary.pivot_table(
index='ID',
columns=['Year', 'Quarter'],
values='Value'
).reset_index()
# 重命名列以便更好地展示
quarterly_wide_summary.columns = [f'{col[0]}_Q{col[1]}' if isinstance(col, tuple) else col for col in quarterly_wide_summary.columns]
quarterly_wide_summary = quarterly_wide_summary.rename(columns={'ID_': 'ID'}) # 修正ID列名
print("\n宽格式的季度汇总结果:")
print(quarterly_wide_summary)输出示例:
宽格式的季度汇总结果: ID 2010_Q1 2010_Q2 2010_Q3 2011_Q1 0 A 10.0 47.0 29.0 21.0 1 B 14.0 61.0 37.0 35.0
本教程详细介绍了如何利用Pandas库将宽格式的月度数据转换为季度和年度汇总数据。核心步骤包括:
掌握这些Pandas技巧,将极大地提高处理和分析时间序列数据的效率和灵活性。
以上就是Pandas DataFrame月度数据按季度和年度汇总教程的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号