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

pandas合并DataFrame时能否限制指定数据框行的最大使用次数

实现思路

核心是先保留dfA的原始顺序和dfB的行顺序,通过同type关联得到所有候选匹配,再按优先级筛选结果,保证每个dfB行的使用次数不超过其n值:

  1. 给dfA加原始索引列,避免排序打乱原有顺序;给dfB加自身行索引,唯一标识每一行
  2. 按type关联两个表,得到同type下的所有匹配组合
  3. 按dfA原始顺序、dfB行顺序排序,保证匹配优先级符合要求
  4. 控制每个dfB行的使用次数不超过n,同时每个dfA行只保留第一个匹配到的结果
  5. 左连接回原始dfA,无匹配的name字段填充为NO MATCH

代码实现

import pandas as pd

def match_df(dfA, dfB):
    # 添加索引保留原有顺序
    dfA = dfA.reset_index(names='orig_idx')
    dfB = dfB.reset_index(names='b_idx')
    
    # 按type关联所有同类型候选
    merged = dfA[['orig_idx', 'type']].merge(dfB, on='type', how='left')
    
    # 按优先级排序:先按dfA原始顺序,再按dfB行顺序
    merged = merged.sort_values(by=['orig_idx', 'b_idx'], ignore_index=True)
    
    # 控制每个dfB行的使用次数不超过对应n值
    merged['b_used_cnt'] = merged.groupby('b_idx').cumcount() + 1
    merged = merged[merged['b_used_cnt'] <= merged['n']]
    
    # 每个dfA行只保留第一个匹配到的结果
    merged = merged.drop_duplicates(subset=['orig_idx'], keep='first')
    
    # 左连接回原dfA,填充无匹配的值
    res = dfA.merge(merged[['orig_idx', 'name']], on='orig_idx', how='left')
    res['name'] = res['name'].fillna('NO MATCH')
    
    # 按原始顺序返回结果,去掉辅助列
    return res.sort_values(by='orig_idx')[['type', 'name']].reset_index(drop=True)

测试验证

第一个示例测试

# 构造第一个示例数据
dfA = pd.DataFrame({'type': ['A', 'B', 'A', 'B', 'A']})
dfB = pd.DataFrame({
    'type': ['A', 'B', 'A', 'B'],
    'name': ['123', '123', '456', '789'],
    'n': [1, 1, 1, 1]
})

print(match_df(dfA, dfB))

第二个示例测试

# 调整dfA顺序为第二个示例的输入
dfA = pd.DataFrame({'type': ['B', 'A', 'B', 'A', 'B']})
print(match_df(dfA, dfB))

两次运行结果完全符合需求规则,dfB行使用次数不超过n值,无匹配时返回NO MATCH。

内容的提问来源于stack exchange,提问作者Jan T.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 17:57:03