Pandas按条件跨DataFrame替换指定列值出现空值问题
问题根因
循环赋值出现空值,是因为df2.loc[df2['loan_num'] == loan, col]返回的是带pandas原生索引的Series对象,不是单个数值。pandas做DataFrame赋值时默认会按索引对齐匹配,只要df1目标行的索引和df2取出的Series索引不匹配,对应位置就会被填充为空值。
哪怕两个表内容完全一样,只要行顺序、索引值有偏差,就会出现你遇到的赋值为空的问题——这也是为什么你赋值固定值时没问题,赋值df2的切片就出问题。
解决方法
方案1:最小改动修复原有循环
只需要在取df2的值时,把带索引的Series转成纯标量值,跳过索引对齐逻辑即可,原有双层循环结构完全不用改:
for loan in fb_loans: for col in cols_to_reset: # 加.iloc[0]取出匹配到的第一个值,转成无索引的标量 new_val = df2.loc[df2['loan_num'] == loan, col].iloc[0] df1.loc[df1['loan_num'] == loan, col] = new_val
方案2:向量化批量替换(推荐,适配多列/大数据量场景)
手写双层循环效率很低,你有数千条记录、30个待重置列的场景,用pandas原生的索引匹配批量替换性能会好很多,代码也更简洁:
# 以贷款编号为索引建立df2的值映射 df2_map = df2.set_index('loan_num') # 标记需要回滚的行 rollback_mask = df1['fb'] == 'Y' # 批量替换指定列,末尾加.values跳过索引对齐 df1.loc[rollback_mask, cols_to_reset] = df2_map.loc[df1.loc[rollback_mask, 'loan_num'], cols_to_reset].values
执行后得到的df1完全匹配你的预期结果:
loan_num bal rate sfee fb 0 100 125000 2.250 0.30 Y 1 101 100000 3.750 0.19 N 2 102 150000 4.000 0.25 N 3 103 275000 4.250 0.75 Y 4 104 350000 6.125 0.25 N 5 105 550000 2.500 0.55 Y
内容的提问来源于stack exchange,提问作者gernworm
相关产品推荐
相关产品推荐

