从我的分析中,我可以看到这个函数需要更多的时间来处理。如何加快此代码的速度?我的数据集有超过一百万条记录,我在这里给出的这个停止词列表只是一个样本——它实际上包含150个单词。

def remove_if_name_v1(s):
    stopwords = ('western spring','western sprin','western spri','western spr','western sp','western s',
                 'grey lynn','grey lyn','grey ly','grey l')
    for word in stopwords:
        s = re.sub(r'(' + word + r'.*?|.*?)\b' + word + r'\b', r'\1', s.lower(), 1)
    return s.title()

test.new_name = test.old_name.apply(lambda x: remove_if_name_v2(x) if pd.notnull(x) else x)

似乎函数是为数据帧中的每一行运行的,在每一行中,它运行for循环的次数与停止字的次数相同。有其他方法吗?
我在这里做的是一个例子,如果字符串包含“西春路西春”,这个函数将返回“西春路”。
谢谢。

最佳答案

一个快速的改进是把停止词放在一个集合中。当检查时,多个单词将导致一个恒定的时间O(1)查找。

STOP_WORDS = {
    'western spring',
    'western sprin',
    'western spri',
    'western spr',
    'western sp',
    'western s',
    'grey lynn',
    'grey lyn',
    'grey ly',
    'grey l'
}

def find_first_stop(words):
    if len(words) == 0:
        return False
    joined = ' '.join(reversed(words))
    if joined in STOP_WORDS:
        return True
    return find_first_stop(words[:-len(words) - 1])

def remove_if_name_v1(s):
    if s in STOP_WORDS:
        return s

    words = []
    split_words = s.split(' ')
    for word in reversed(split_words):
        words.append(word)
        if find_first_stop(words):
            words = []
    return ' '.join(reversed(words))

old_name = pd.Series(['western spring road western spring', 'kings road western spring', 'western spring'])
new_name = old_name.apply(lambda x: remove_if_name_v1(x) if pd.notnull(x) else x)
print(new_name)

输出:
0    western spring road
1             kings road
2         western spring
dtype: object

关于python - 加快循环速度-python,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45092752/

10-11 06:40