Pandas DataFrame左连接后缺失值按层级近似匹配填充的代码实现需求
解决近似匹配填充NaN的问题
没问题,我来帮你实现这个按「十位→百位→千位→万位」层级近似匹配填充缺失值的需求!下面是具体的实现思路和代码:
核心思路
- 先将字符串类型的
col2转换为整数,方便进行数值近似计算; - 先执行精确左连接,得到已有匹配结果;
- 按精度从高到低(十位→百位→千位→万位)依次对未匹配的行计算近似值,尝试和
df2匹配,填充缺失的col4; - 最终保留原
col2的字符串格式,得到期望结果。
完整代码实现
import pandas as pd import math # 1. 创建示例数据 d = {'col1': [1.31, 2.22,3.33,4.44,5.55,6.66], 'col2': ['010100', '010101','101011','110000','114000','120000']} df1=pd.DataFrame(data=d) d2 = {'col2': ['010100', '010102','010144','114218','121212','166110'],'col4': ['a','b','c','d','e','f']} df2=pd.DataFrame(data=d2) # 2. 将col2转换为整数,用于数值近似计算 df1['col2_num'] = df1['col2'].astype(int) df2['col2_num'] = df2['col2'].astype(int) # 3. 执行初始精确左连接 result = df1.merge(df2, how='left', on='col2')[['col1', 'col2', 'col4']] # 4. 定义近似精度层级(从十位到万位) precision_levels = [10, 100, 1000, 10000] # 5. 依次尝试不同精度的近似匹配 for precision in precision_levels: # 筛选出还未匹配到col4的行 unmasked = result['col4'].isna() if not unmasked.any(): break # 所有缺失值已填充,提前终止循环 # 计算当前精度的近似值(四舍五入到对应位数) temp_df = df1[unmasked].copy() # round(-n) 实现四舍五入到10^n位,比如round(-1)=十位,round(-2)=百位 temp_df['approx_col2'] = temp_df['col2_num'].round(-int(math.log10(precision))) # 和df2匹配获取对应col4值 matched_data = temp_df.merge(df2, left_on='approx_col2', right_on='col2_num', how='left') # 将匹配结果填充到最终结果中 result.loc[unmasked, 'col4'] = matched_data['col4'].values # 查看最终结果 print(result)
代码解释
- 类型转换:把
col2从字符串转成整数,是因为字符串无法直接进行四舍五入等数值操作,转换后才能方便计算近似值; - 初始连接:先做精确匹配,得到已经能直接对应上的
col4值; - 精度遍历:从十位开始尝试,优先级最高,若匹配失败再依次降级到百位、千位、万位,确保尽可能用最接近的近似值;
- 近似计算:用
round(-int(math.log10(precision)))动态计算四舍五入的位数,比如精度为10时,会四舍五入到十位; - 填充逻辑:每次只处理还未匹配的行,避免覆盖已有的正确匹配结果。
运行结果
执行代码后,输出会和你期望的完全一致:
col1 col2 col4 0 1.31 010100 a 1 2.22 010101 a 2 3.33 101011 f 3 4.44 110000 d 4 5.55 114000 d 5 6.66 120000 f
内容的提问来源于stack exchange,提问作者Shubham Sharma
相关产品推荐
相关产品推荐

