You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

两个DataFrame按SAMPFROM匹配替换C-ORG列-99值的实现方法

问题说明

现有两个DataFrame,需按规则匹配合并C-ORG列:当两个表的SAMPFROM列取值相等时,用data2中对应的C-ORG值,替换data1中对应位置的-99值。
两个测试数据集结构如下:

data1

SAMPFROMSAMPTOC-ORG
05-99
510-99
1015-99
1520-99
2025-99
2530-99
3035-99
3540-99
4045-99

data2

SAMPFROMSAMPTOC-ORG
0202.5
20407
40607
60809

原有测试代码未达到预期,代码如下:

LIST1=list(data1['SAMPFROM'])
LIST2=list(data2['SAMPFROM'])
values=[]
for i in LIST1:
 for j in LIST2:
    if i==j:
        values.append(i)
for k in values:
 for q in data2['SAMPFROM']:
    if k==q:
        data1['new']=data2['CO3_pct_BESTEL']
原因分析

原代码存在三个核心问题:

  • 列名引用错误:data2中不存在CO3_pct_BESTEL列,目标替换列名为C-ORG
  • 赋值逻辑错误:循环中每次匹配到值都直接给整列赋值,会被后续循环结果覆盖,且两个DataFrame长度不一致,直接整列赋值会出现索引错位
  • 实现方式低效:多层嵌套循环在数据量稍大时性能极差,pandas原生提供了专门的映射、合并方法,不需要手写循环实现
解决方案

方案1:严格按「SAMPFROM值相等」规则替换

如果需求确实是仅当两个表SAMPFROM值完全相等时才替换,用映射字典实现即可,代码简洁且运行效率高:

# 构建SAMPFROM到C-ORG的映射关系
corg_map = data2.set_index('SAMPFROM')['C-ORG'].to_dict()

# 逐行判断替换:原C-ORG为-99且SAMPFROM存在匹配值时,用映射值替换
data1['C-ORG'] = data1.apply(
    lambda x: corg_map[x['SAMPFROM']] if x['C-ORG'] == -99 and x['SAMPFROM'] in corg_map else x['C-ORG'],
    axis=1
)

运行后data1中SAMPFROM为0、20、40的三行C-ORG会被替换为2.5、7、7,其余行因无匹配SAMPFROM保留-99。

方案2:按区间匹配替换(更符合样本分段数据的常规逻辑)

从两个表的SAMPTO字段可以看出,data2是分段区间数据,如果实际需求是data1的SAMPFROM落在data2对应[SAMPFROM, SAMPTO)区间时,就用该区间的C-ORG替换-99,可以用pandas的merge_asof实现近似区间匹配,不需要手写循环判断区间:

import pandas as pd

# merge_asof要求关联键必须先排序
data1_sorted = data1.sort_values('SAMPFROM').reset_index(drop=True)
data2_sorted = data2.sort_values('SAMPFROM').reset_index(drop=True)

# 左连接匹配最近的、不大于当前SAMPFROM的data2记录
merge_res = pd.merge_asof(
    data1_sorted,
    data2_sorted[['SAMPFROM', 'C-ORG']],
    on='SAMPFROM',
    direction='backward',
    suffixes=('', '_match')
)

# 替换-99值,删除临时列
merge_res['C-ORG'] = merge_res.apply(
    lambda x: x['C-ORG_match'] if x['C-ORG'] == -99 else x['C-ORG'],
    axis=1
)
data1_result = merge_res.drop(columns=['C-ORG_match'])

运行后所有行的C-ORG都会被正确填充:

  • SAMPFROM属于[0,20)区间(0、5、10、15)的行,C-ORG为2.5
  • SAMPFROM属于[20,40)区间(20、25、30、35)的行,C-ORG为7
  • SAMPFROM属于[40,60)区间(40、45)的行,C-ORG为7

内容的提问来源于stack exchange,提问作者Taiwo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 17:33:44