Pandas多列合并时忽略NaN值的高效实现方案求助
高效实现方案
你可以用numpy广播机制实现批量匹配,完全避免Python级别的逐行循环,性能远高于iterrows遍历方案,6个level列的场景也可以轻松适配:
完整代码
import pandas as pd import numpy as np # 示例数据构造 df1 = pd.DataFrame([[0, 1, 3], [0, 2, 4], [1, 2, 5]], columns=['level1', 'level2', 'level3']) df2 = pd.DataFrame([[0, None, None, 10], [0, 1, None, 12], [None, 2, 5, 13]], columns=['level1', 'level2', 'level3', 'value']) # 配置level列,你的业务场景改成6个对应的列名即可 level_cols = ['level1', 'level2', 'level3'] # 提取数组用于广播计算 arr1 = df1[level_cols].values arr2 = df2[level_cols].values value_arr = df2['value'].values # 生成df2非空匹配列的掩码(支持所有数据类型,不限于数值) mask2 = df2[level_cols].notna().values # 批量计算匹配结果:对于每个df2行,判断df1所有行的非空level列是否全部匹配 match_flag = ((arr1[:, np.newaxis] == arr2) | ~mask2).all(axis=2) # 提取所有匹配的行对索引 df1_idx, df2_idx = np.where(match_flag) # 拼接生成最终结果 result = pd.concat([ df1.iloc[df1_idx].reset_index(drop=True), pd.Series(value_arr[df2_idx], name='value') ], axis=1) print(result)
输出结果
level1 level2 level3 value 0 0 1 3 10 1 0 1 3 12 2 0 2 4 10 3 1 2 5 13
方案说明
- 核心逻辑通过numpy的广播特性,一次性计算所有df1和df2行的匹配关系,所有计算都在C语言层面执行,性能极高
- 对任意非空level列组合都可以自动适配,不需要提前枚举所有可能的匹配规则
- 非数值类型的level列也可以兼容,只需要保证
==判断符合你的业务匹配逻辑即可
内容的提问来源于stack exchange,提问作者Aryerez
相关产品推荐
相关产品推荐

