如何用Pandas将多组日期关联列转换为统一日期索引的DataFrame
解决方案
首先,先确认原始数据的生成代码(模拟你的输入):
import pandas as pd import numpy as np # 生成包含多组日期-数值列的原始DataFrame df_raw = pd.DataFrame({ 'date1': pd.date_range('2023-01-01', periods=5), 'X1': np.random.randint(1, 100, 5), 'date2': pd.date_range('2023-01-03', periods=5), 'X2': np.random.randint(1, 100, 5), 'date3': pd.date_range('2023-01-02', periods=5), 'X3': np.random.randint(1, 100, 5) })
下面提供三种高效的实现方式,按需选择:
方法1:拆分合并法(直观易理解)
这种方法适合刚接触Pandas的用户,步骤清晰:
# 拆分每组日期-数值列,统一日期列名并设为索引 df1 = df_raw[['date1', 'X1']].rename(columns={'date1': 'date'}).set_index('date') df2 = df_raw[['date2', 'X2']].rename(columns={'date2': 'date'}).set_index('date') df3 = df_raw[['date3', 'X3']].rename(columns={'date3': 'date'}).set_index('date') # 合并所有子DataFrame,缺失值自动填充NaN final_df = pd.concat([df1, df2, df3], axis=1).sort_index()
关键说明:
- 每组单独提取后重命名日期列,确保索引一致
pd.concat按列合并时,自动对齐索引,缺失位置填充NaNsort_index用于整理日期顺序,方便查看
方法2:使用pd.wide_to_long(专门处理多后缀列)
Pandas内置的wide_to_long函数专门针对这种带数字后缀的列对(如date1/X1、date2/X2),代码最简洁:
# 转换宽表为长表,再重塑为目标宽表 final_df = pd.wide_to_long( df_raw, stubnames=['date', 'X'], # 列名前缀 i=df_raw.index, # 原始行索引作为临时分组键 j='group', # 后缀的别名(可后续删除) sep='' # 前缀与后缀之间无分隔符 ).reset_index().drop('group', axis=1).set_index('date').sort_index() # 处理同一日期的重复值(如果存在),这里保留第一个值 final_df = final_df.groupby('date').first()
关键说明:
- 自动识别后缀数字,批量处理所有列对
- 最后通过
groupby确保同一日期只保留一条记录(若原始数据有重复日期)
方法3:melt+pivot组合(通用重塑方式)
适合处理更复杂的列名规则,灵活性高:
# 先将所有列融合成长格式 melted = df_raw.melt( value_vars=[('date1', 'X1'), ('date2', 'X2'), ('date3', 'X3')], var_name=['date_col', 'X_col'], value_name='temp' ) # 提取对应的日期和数值 melted['date'] = melted.apply(lambda row: df_raw.loc[row.name, row['date_col']], axis=1) melted['value'] = melted.apply(lambda row: df_raw.loc[row.name, row['X_col']], axis=1) # 重塑为目标宽表 final_df = melted.pivot(index='date', columns='X_col', values='value').sort_index() final_df.columns.name = None # 移除列名的层级标签
最终结果示例
X1 X2 X3 date 2023-01-01 45 NaN NaN 2023-01-02 NaN NaN 78 2023-01-03 23 56 NaN 2023-01-04 89 34 12 2023-01-05 17 91 43 2023-01-06 NaN 22 65 2023-01-07 NaN 77 39
内容的提问来源于stack exchange,提问作者Jacques Tebeka
相关产品推荐
相关产品推荐

