如何将两个同结构DataFrame合并为含Name列的目标格式数据表?
解决方法
核心思路
你之前用concat()导致Name列重复,是因为concat()是纵向拼接两个表,而你需要的是按date和Name匹配后横向合并数值列。正确的做法是先分别melt()两个DataFrame,再用merge()按共同键合并,而非concat()。
步骤示例
假设你的原始DataFrame结构如下(date为行索引,列名为各类Name):
import pandas as pd # 示例DF1 df1 = pd.DataFrame( {'Alice': [10, 15], 'Bob': [20, 25]}, index=pd.date_range('2024-01-01', periods=2) ).rename_axis('date') # 示例DF2 df2 = pd.DataFrame( {'Alice': [12, 17], 'Bob': [22, 27]}, index=pd.date_range('2024-01-01', periods=2) ).rename_axis('date')
1. 分别对两个DF做melt处理
将列名(即Name)转为单独列,同时给数值列命名区分来源:
# 处理DF1,重置索引把date转为列 df1_melted = df1.reset_index().melt( id_vars='date', var_name='Name', value_name='DF1_value' ) # 处理DF2,同理 df2_melted = df2.reset_index().melt( id_vars='date', var_name='Name', value_name='DF2_value' )
2. 用merge按date和Name合并
通过date和Name两个键匹配,将两个表的数值列横向合并:
final_df = df1_melted.merge(df2_melted, on=['date', 'Name'], how='inner')
how='inner':只保留两个DF都存在的date+Name组合;如果需要保留所有组合,改用how='outer'。
最终结果
得到的final_df结构如下:
| date | Name | DF1_value | DF2_value |
|---|---|---|---|
| 2024-01-01 | Alice | 10 | 12 |
| 2024-01-01 | Bob | 20 | 22 |
| 2024-01-02 | Alice | 15 | 17 |
| 2024-01-02 | Bob | 25 | 27 |
替代方法(无需先melt)
如果不想先做melt,也可以先给列加前缀再合并,最后转成目标格式:
# 给列名加前缀区分来源 df1_renamed = df1.add_prefix('DF1_') df2_renamed = df2.add_prefix('DF2_') # 按索引合并 combined = df1_renamed.join(df2_renamed).reset_index() # 转长表后拆分列名,再转回宽表 combined_melt = combined.melt(id_vars='date', var_name='source_name', value_name='value') combined_melt[['source', 'Name']] = combined_melt['source_name'].str.split('_', expand=True) final_df = combined_melt.pivot(index=['date', 'Name'], columns='source', values='value').reset_index() final_df.columns = ['date', 'Name', 'DF1_value', 'DF2_value']
内容的提问来源于stack exchange,提问作者complog
相关产品推荐
相关产品推荐

