Pandas:将DataFrame多列重塑为含月末日期的单列结构
解决DataFrame重塑与月末日期生成的方案
嘿,这个需求我之前也碰到过,用pandas的工具就能轻松搞定!我给你一步步拆解实现步骤:
1. 先明确原始数据结构(示例)
假设你的原始DataFrame长这样(包含pointId、年份year,以及12个月份列month1到month12):
import pandas as pd # 模拟你的原始数据 df = pd.DataFrame({ 'pointId': ['P001', 'P002'], 'year': [2022, 2023], 'month1': [12.5, 34.2], 'month2': [15.1, 31.7], 'month3': [18.3, 29.9], # ... 省略month4到month11的示例数据 'month12': [9.8, 22.4] })
2. 第一步:将宽表转为长表
用melt函数把12个月份列合并成「月份标识」和「对应数值」两列,保留pointId和year作为标识列:
# 重塑宽表为长表 melted_df = df.melt( id_vars=['pointId', 'year'], # 保留的标识列 var_name='month_label', # 原月份列的列名会存入这个新列 value_name='metric_value' # 原月份列的数值会存入这个新列 )
3. 第二步:提取月份数字
从month_label(比如month1、month12)里提取出纯数字的月份:
# 从"monthX"中提取数字X,转为整数类型 melted_df['month'] = melted_df['month_label'].str.extract(r'(\d+)').astype(int)
4. 第三步:生成月末日期
结合year和month生成当月的月末日期,这里用pandas的日期偏移量来精准获取月末:
from pandas.tseries.offsets import MonthEnd # 先构造当月第一天的日期,再偏移到当月最后一天 melted_df['end_of_month'] = pd.to_datetime( melted_df[['year', 'month']].assign(day=1) ) + MonthEnd(1)
5. 第四步:整理最终结果
去掉不需要的中间列,调整列顺序,再按pointId和日期排序:
# 筛选并调整列顺序,排序后重置索引 final_df = melted_df[['pointId', 'end_of_month', 'metric_value']].sort_values( by=['pointId', 'end_of_month'] ).reset_index(drop=True)
这样得到的final_df就是你想要的结构:每个月份的数值单独一行,日期列对应当月月末。
如果你的原始月份列命名不是month1这种格式(比如直接是1月、Jan),只需要调整提取月份数字的逻辑就行,核心思路是通用的~
内容的提问来源于stack exchange,提问作者Fizi
相关产品推荐
相关产品推荐

