Pandas外连接合并DataFrame:将右表缺失值填充为0或NaN
实现全组合匹配并填充缺失值的优雅方法
这个需求本质是要生成Name和Shape的所有可能组合,再把对应的Color和Value补全,外连接确实做不到自动生成全组合,我给你两种优雅的实现方式,都能满足你的需求:
方法一:分步生成笛卡尔积(直观可控)
这种方式步骤清晰,适合需要明确掌控每一步逻辑的场景:
- 先准备好示例数据:
import pandas as pd df1 = pd.DataFrame({ 'Name': ['Tom', 'Frank', 'John', 'Sarah'], 'Color': ['Blue', 'Red', 'Green', 'Red'] }) df2 = pd.DataFrame({ 'Name': ['Tom', 'Tom', 'Frank', 'John', 'Sarah'], 'Shape': ['Circle', 'Square', 'Triangle', 'Square', 'Circle'], 'Value': [4, 4, 7, 2, 1] })
- 生成Name和Shape的所有可能组合(笛卡尔积):
# 提取所有唯一的Name和Shape all_names = df1['Name'].unique() all_shapes = df2['Shape'].unique() # 生成全组合DataFrame full_combinations = pd.MultiIndex.from_product( [all_names, all_shapes], names=['Name', 'Shape'] ).to_frame(index=False)
- 逐步合并并填充缺失值:
# 合并df1拿到每个Name对应的Color merged = full_combinations.merge(df1, on='Name', how='left') # 合并df2拿到Value,并用0填充缺失的Value final_df = merged.merge(df2, on=['Name', 'Shape'], how='left').fillna({'Value': 0}) # 调整列顺序和你期望的一致 final_df = final_df[['Name', 'Color', 'Shape', 'Value']]
方法二:用Pivot+Melt实现(简洁高效)
如果喜欢更紧凑的代码,可以用透视表+列转行的方式,一步到位:
import pandas as pd # 先把df2转成宽表,自动用0填充缺失的Value df2_pivot = df2.pivot_table( index='Name', columns='Shape', values='Value', fill_value=0 ) # 和df1合并后,把Shape列转回行,调整格式 final_df = df1.merge(df2_pivot, on='Name', how='left') \ .melt( id_vars=['Name', 'Color'], var_name='Shape', value_name='Value' ) \ .sort_values(['Shape', 'Name']) \ .reset_index(drop=True)
两种方法运行后,都会得到你想要的DFM结果,缺失的Value已经自动填充为0。如果你更倾向先保留NaN再手动替换,只需要去掉fill_value=0或者fillna({'Value':0})即可。
内容的提问来源于stack exchange,提问作者pacificdune
相关产品推荐
相关产品推荐

