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

基于多列区间条件匹配Pandas两个DataFrame行并生成匹配列表

解决方案:给Pandas DataFrame每行追加匹配的已知库结果列表

嘿,这个需求其实挺常见的,咱们可以用Pandas结合numpy的矢量化操作来高效实现,也可以用更直观的逐行遍历方式(适合小数据量)。下面给你两种可行的方案,附带示例代码,你可以直接套用到自己的数据上:

先构造示例数据(方便你理解)

首先咱们先模拟你的主数据df和已知库kd,这样你能直接运行代码看效果:

import pandas as pd
import numpy as np

# 主数据df:包含需要匹配的每行数据
df = pd.DataFrame({
    'id': ['pt1', 'pt2', 'pt3'],
    'f': [15, 25, 8],
    'p': [35, 45, 28],
    'w': [55, 65, 48]
})

# 已知库kd:包含区间匹配规则和对应的标识(比如db1、db3)
kd = pd.DataFrame({
    'db_id': ['db1', 'db2', 'db3'],
    'f_lo': [10, 20, 12],
    'f_hi': [20, 30, 18],
    'p_lo': [30, 40, 32],
    'p_hi': [40, 50, 38],
    'w_lo': [50, 60, 52],
    'w_hi': [60, 70, 58]
})

方案一:矢量化操作(推荐大数据量)

这个方案利用numpy的广播特性,避免了Python层面的逐行循环,效率极高,适合数据量较大的场景:

# 把kd的条件列和标识列转换成numpy数组,方便广播计算
f_lo = kd['f_lo'].values
f_hi = kd['f_hi'].values
p_lo = kd['p_lo'].values
p_hi = kd['p_hi'].values
w_lo = kd['w_lo'].values
w_hi = kd['w_hi'].values
db_ids = kd['db_id'].values

# 定义匹配函数:输入df的一行,返回匹配的db_id列表
def get_matched_dbs(row):
    # 广播计算每个kd行是否满足三个区间条件
    match_mask = (f_lo < row['f']) & (row['f'] < f_hi) & \
                 (p_lo < row['p']) & (row['p'] < p_hi) & \
                 (w_lo < row['w']) & (row['w'] < w_hi)
    # 返回匹配到的db_id列表
    return db_ids[match_mask].tolist()

# 给df新增'matched_dbs'列,存储每行的匹配结果
df['matched_dbs'] = df.apply(get_matched_dbs, axis=1)

方案二:逐行遍历(小数据量更直观)

如果你的数据量不大,这个方案逻辑更直白,容易理解和调试:

# 定义逐行匹配函数
def get_matched_dbs_simple(row):
    matched_list = []
    # 遍历已知库kd的每一行,判断是否满足条件
    for _, kd_row in kd.iterrows():
        if (kd_row['f_lo'] < row['f'] < kd_row['f_hi']) and \
           (kd_row['p_lo'] < row['p'] < kd_row['p_hi']) and \
           (kd_row['w_lo'] < row['w'] < kd_row['w_hi']):
            matched_list.append(kd_row['db_id'])
    return matched_list

# 新增匹配结果列
df['matched_dbs'] = df.apply(get_matched_dbs_simple, axis=1)

运行结果示例

执行完上面的代码后,df会变成这样:

id   f   p   w matched_dbs
0  pt1  15  35  55  [db1, db3]
1  pt2  25  45  65        [db2]
2  pt3   8  28  48          []

可以看到pt1正好匹配到了db1和db3,和你描述的需求一致~

一些注意事项

  • 如果你的df和kd列名和示例不一样,记得替换代码中对应的列名;
  • 如果你需要匹配的是kd的整行数据(而不仅仅是db_id),只需要把db_ids[match_mask]换成kd[match_mask].to_dict('records')即可;
  • 数据量较大时(比如kd有上万行),优先选方案一,numpy的广播操作比Python循环快几十倍甚至上百倍。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 10:21:40