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

如何用Python高效匹配DataFrame中词占比≥75%的字符串?

无关联列的DataFrame词占比匹配实现

核心思路

通过集合运算结合pandas的向量化操作,替代逐行迭代,高效计算短描述词在长描述中的占比,筛选符合≥75%要求的匹配对。

实现步骤

假设已完成特殊字符与重音去除,df1存储短描述(列名short_desc),df2存储长描述(列名long_desc):

  1. 生成词集合列
    将文本拆分为词集合,方便后续计算交集:

    import pandas as pd
    
    # 示例数据
    df1 = pd.DataFrame({'short_desc': ['苹果 红色 水果', '香蕉 黄色 长条']})
    df2 = pd.DataFrame({'long_desc': ['红色苹果是常见水果,口感清甜', '黄色香蕉为热带长条水果,富含钾']})
    
    # 转换为词集合
    df1['short_words'] = df1['short_desc'].str.split().apply(set)
    df2['long_words'] = df2['long_desc'].str.split().apply(set)
    
  2. 生成笛卡尔积匹配对
    构建两个DataFrame所有行的组合,为后续计算做准备:

    # 生成笛卡尔积索引并转为DataFrame
    cross_idx = pd.MultiIndex.from_product([df1.index, df2.index], names=['df1_idx', 'df2_idx'])
    cross_df = pd.DataFrame(index=cross_idx).reset_index()
    
    # 合并词集合列
    cross_df = cross_df.merge(df1[['short_words']], left_on='df1_idx', right_index=True)
    cross_df = cross_df.merge(df2[['long_words']], left_on='df2_idx', right_index=True)
    
  3. 计算匹配占比并筛选
    用集合交集计算短描述词在长描述中的覆盖比例,筛选符合阈值的结果:

    # 计算词占比:短描述匹配词数 / 短描述总词数
    cross_df['match_ratio'] = cross_df.apply(
        lambda x: len(x['short_words'] & x['long_words']) / len(x['short_words']),
        axis=1
    )
    
    # 筛选占比≥75%的匹配对
    matched_pairs = cross_df[cross_df['match_ratio'] >= 0.75]
    
    # 合并原数据得到最终结果
    final_result = matched_pairs.merge(df1, left_on='df1_idx', right_index=True) \
                                .merge(df2, left_on='df2_idx', right_index=True) \
                                .drop(['short_words', 'long_words'], axis=1)
    

性能优化

如果数据量较大,可借助swifter库加速apply操作(自动选择最优执行方式):

import swifter

cross_df['match_ratio'] = cross_df.swifter.apply(
    lambda x: len(x['short_words'] & x['long_words']) / len(x['short_words']),
    axis=1
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 10:01:21