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

如何优化将字符串列表转为层级DataFrame的低效函数?

层级术语DataFrame构建的性能优化问题

需求说明

我有一个包含数千条字符串的列表,需将其整理为层级DataFrame:每行对应单个术语的完整路径,每列为可变层级,所有行中列x的字符串需以整词形式完整包含于列x+1的字符串(仅为单词内子串时不匹配)。示例输入如下:

terms = ["term a",
         "term a term b",
         "word",
         "word a term b",
         "words",
         "contains words",
         "term a contains",
         "term b contains words",
         "term a term b contains words"]

期望输出为指定结构的层级DataFrame。

现状

我已实现organize_terms函数满足需求,但处理大量数据时速度极慢,核心瓶颈为带边界的re.search操作。后续我用nltk的ngrams实现了search函数替代,速度有所提升,但仍希望进一步优化性能。现寻求该函数的优化或重构建议。

现有代码

organize_terms函数

import pandas as pd
import re
import itertools

def organize_terms(terms):

    levels = {}
    path = {}
    terms_copy = terms.copy()

    # 确定每个术语所属的层级
    count = 0

    while len(terms) > 0:

        levels[f"level_{count}"] = []

        for term in terms:
            # 找出当前术语集合中,比当前术语短且整词包含于当前术语的所有术语
            temp = [term_2 for term_2 in terms if re.search(r"\b{}\b".format(term_2), term) != None and len(term_2.split()) < len(term.split())]
            # 无匹配项则当前术语为当前层级的根节点
            if temp == []:
                levels[f"level_{count}"].append(term)
        
        # 移除已分配层级的术语,继续处理剩余内容
        terms = [x for x in terms if x not in levels[f"level_{count}"]]
        
        count += 1

    """
    levels 最终结构示例:
    {'level_0': ['term a', 'word', 'words'],
     'level_1': ['term a term b', 'word a term b', 'contains words', 'term a contains'],
     'level_2': ['term b contains words'],
     'level_3': ['term a term b contains words']}
    """

    # 初始化路径字典,每个层级对应空列表
    for key in levels.keys():
        path[key] = []

    # 为每个原始术语构建所有合法路径
    for term in terms_copy:

        # 收集每个层级中整词包含于当前术语的所有术语
        matches = []
        for level in levels.keys():
            level_match = [term_2 for term_2 in levels[level] if re.search(r"\b{}\b".format(term_2), term) != None]
            if level_match != []:
                matches.append(level_match)

        # 生成所有层级匹配术语的笛卡尔积(所有可能的路径组合)
        combinations = list(itertools.product(*matches))

        """
        combinations 示例:
        对于"term a":[('term a',)]
        对于"term a term b":[('term a', 'term a term b')]
        对于"term a term b contains words":
        [('term a', 'term a term b', 'term b contains words', 'term a term b contains words'),
         ('term a', 'contains words', 'term b contains words', 'term a term b contains words'),
         ('words', 'term a term b', 'term b contains words', 'term a term b contains words'),
         ('words', 'contains words', 'term b contains words', 'term a term b contains words')]
        """

        # 验证路径组合是否满足层级递进关系(前一层术语整词包含于后一层)
        for combination in combinations:
            confirmation = all([re.search(r"\b{}\b".format(combination[i-1]), combination[i]) != None for i in range(1, len(combination))])
            if confirmation:
                list_combination = list(combination)
                # 补全路径到最大层级数,不足位置用None填充
                while len(list_combination) < len(levels.keys()):
                    list_combination.append(None)
                # 将路径各层级术语添加到对应列表
                for idx, combination_term in enumerate(list_combination):
                    path[f"level_{idx}"].append(combination_term)
         
    """
    path 最终结构示例:
    {'level_0': ['term a', 'term a', 'word', 'word', 'words', 'words', 'term a', 'words', 'words'],
     'level_1': [None, 'term a term b', None, 'word a term b', None, 'contains words', 'term a contains', 'contains words', 'contains words'],
     'level_2': [None, None, None, None, None, None, None, 'term b contains words', 'term b contains words'],
     'level_3': [None, None, None, None, None, None, None, None, 'term a term b contains words']}
    """

    # 转换为DataFrame并返回
    return pd.DataFrame(path)

替代search函数

from nltk import ngrams

def search(term1, term2):
    # 将term2按词分割后,生成长度等于term1词数的ngram并拼接为字符串
    ngram_list = [' '.join(tuples) for tuples in list(ngrams(term2.split(), len(term1.split())))]
    # 判断term1是否为term2的连续整词子串
    return term1 in ngram_list

内容的提问来源于stack exchange,提问作者Eduardo Ramon Resser

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 09:01:43