Pandas中不同结构DataFrame的合并与透视实现方法
合并三类气象水文监测宽表的实现方法
核心思路
三个表的行索引均为日期,只需将降水、温度两个单层列宽表调整为和水位表一致的*「站点编号SiteNo + 监测要素名」两级列索引*结构,再按列横向合并即可,Pandas会自动对齐所有日期的并集。
该方法无需手动转换长表合并,避免了多次长宽表转换带来的索引错位、字段匹配错误等问题。
具体实现步骤
1. 统一日期索引格式
首先确保三个表的行索引均为datetime类型,避免日期格式不匹配导致的合并错位:
# 水位表的日期已完成类型转换,无需额外处理 # 转换降水表的日期索引为datetime格式 df_precip.index = pd.to_datetime(df_precip.index, errors='coerce') # 转换温度表的日期索引为datetime格式 df_temp.index = pd.to_datetime(df_temp.index, errors='coerce') # 剔除日期为空的无效行 df_precip = df_precip.dropna(how='all') df_temp = df_temp.dropna(how='all')
2. 统一列索引结构
给降水、温度表添加二级列索引,和水位表的列结构对齐:
# 为降水表添加二级列索引,标识要素为"Precip" df_precip.columns = pd.MultiIndex.from_product( [df_precip.columns, ['Precip']], names=['SiteNo', 'Element'] ) # 为温度表添加二级列索引,标识要素为"Temp" df_temp.columns = pd.MultiIndex.from_product( [df_temp.columns, ['Temp']], names=['SiteNo', 'Element'] ) # 统一水位表的列索引名称,和其他表保持一致 df_WL.columns.names = ['SiteNo', 'Element']
3. 横向合并三个宽表
直接按列合并,默认会取所有日期的并集,无对应数据的位置自动填充空值:
# 按列合并三个表,join='outer'为默认值,保留所有日期的并集;若需仅保留共有日期可改为join='inner' merged_df = pd.concat([df_WL, df_precip, df_temp], axis=1, join='outer') # 按站点编号、要素名排序,优化列顺序 merged_df = merged_df.sort_index(axis=1)
(可选)转换为长表格式
如果后续需要使用包含Date、SiteNo、WL、Temp、Precip字段的长表,可直接通过宽表转换实现,无需手动合并:
# 宽表转长表,自动对齐所有要素 merged_long = merged_df.stack(level='SiteNo', future_stack=True).reset_index()
注意事项
- 合并前需确保三个表的站点编号类型统一,建议提前将所有站点列/索引都转为字符串类型,避免数值型、字符串型站点不匹配的问题
- 若需要仅保留三个数据集都有记录的日期,可在
pd.concat中添加join='inner'参数
内容的提问来源于stack exchange,提问作者Jacob
相关产品推荐
相关产品推荐

