如何在Python/Pandas中合并匹配不同长度的DataFrame
合并多个DataFrame并按值匹配生成宽表
解决方案思路
你需要将所有DataFrame中的label值作为唯一行,每个原DataFrame对应一列,显示该行值是否在该DataFrame中(不存在则为null)。核心步骤是先统一每个DataFrame的索引为label,再通过外连接合并所有表,最后整理格式。
代码实现
1. 准备示例数据
import pandas as pd # 示例DataFrame df1 = pd.DataFrame({'id': [1,2,3], 'label': ['a-1', 'b-2', 'z-10']}) df2 = pd.DataFrame({'id': [1,2,3], 'label': ['b-2', 'd-4', 'e-5']}) df3 = pd.DataFrame({'id': [1,2,3], 'label': ['a-1', 'd-4', 'f-6']})
2. 批量处理DataFrame
定义通用处理函数,将每个DataFrame转换为以label为索引、仅保留对应列的格式:
def process_single_df(df, df_name): # 以label为索引,创建对应名称的列存储label值 return df.set_index('label')[[]].assign(**{df_name: df['label']})
3. 合并所有处理后的表
如果有12+个DataFrame,只需将它们放入列表循环处理即可:
# 存储所有处理后的DataFrame processed_dfs = [] # 假设你的DataFrame列表是dfs,名称列表是df_names(比如['df1','df2',...,'df12']) # 这里用示例数据演示 dfs = [df1, df2, df3] df_names = ['df1', 'df2', 'df3'] for df, name in zip(dfs, df_names): processed_dfs.append(process_single_df(df, name)) # 外连接合并所有表,缺失值自动填充为NaN final_df = pd.concat(processed_dfs, axis=1, join='outer')
4. 整理最终格式
重置索引、添加行号id,并将NaN替换为null:
# 重置索引,恢复label列 final_df = final_df.reset_index().rename(columns={'index': 'label'}) # 添加行号作为id列 final_df.insert(0, 'id', final_df.index + 1) # 调整列顺序,只保留需要的列 final_df = final_df[['id'] + df_names] # 将NaN替换为字符串'null' final_df = final_df.fillna('null')
执行后得到的结果与你期望的完全一致:
id df1 df2 df3 0 1 a-1 null a-1 1 2 b-2 b-2 null 2 3 null d-4 d-4 3 4 null e-5 null 4 5 null null f-6 5 6 z-10 null null
为什么之前的方法不行
join默认是按索引或指定列(比如原id)匹配,而你需要的是按label值的全局集合匹配,普通join无法自动收集所有label值作为行。insert只能手动添加列,无法动态扩展行来容纳所有label值,也无法自动匹配对应值的位置。
内容的提问来源于stack exchange,提问作者KHibma
相关产品推荐
相关产品推荐

