在 pandas 中使用 Levenshtein 比较字符串时提高 Python 代码性能

Improving Python code performance when comparing strings using Levenshtein in pandas

我有这段代码可以正常运行并产生我正在寻找的结果:

from thefuzz import fuzz
import pandas as pd

df = pd.read_csv('/folder/folder/2011_05-rc.csv', dtype=str, lineterminator='\n')
df_compare = pd.DataFrame(
    df['text'].apply(lambda row: [fuzz.partial_ratio(x, row) for x in df['text']]).to_list())

for i in df_compare.index:
    for j in df_compare.columns[i:]:
        df_compare.iloc[i, j] = 0

df[df_compare.max(axis=1) < 75].to_csv('/folder/folder/2011_05-ready.csv', index=False)

print('Done did')

但是,由于字符串比较是一项成本非常高的操作,因此该脚本非常慢,并且只能处理 5000-7000 行的相对较小的 CSV 文件。任何大的(超过 12MB)都需要几天才能抛出与内存相关的错误消息。我尝试 运行 在 32 个内核和 32 GB 内存上使用 modin,但它没有改变任何东西,我最终得到了相同的结果。

import glob
from thefuzz import fuzz
import modin.pandas as pd

files = glob.glob('/folder/folder/2013/*.csv')

for file in files:
    df = pd.read_csv(file, dtype=str, lineterminator='\n')
    f_compare = pd.DataFrame(
        df['text'].apply(lambda row: [fuzz.partial_ratio(x, row) for x in df['text']]).to_list())

    for i in df_compare.index:
        for j in df_compare.columns[i:]:
            df_compare.iloc[i, j] = 0

    df[df_compare.max(axis=1) < 75].to_csv(f'{file[:-4]}-done.csv', index=False)
    print(f'{file} has been done')

它作为一项单独的工作处理较小的文件 运行,但文件太多而无法单独完成。有没有办法优化此代码或其他一些可能的解决方案?

数据是推文的集合,而只有一列被比较(大约 30 列)。它看起来像这样:

ID Text
11213 I am going to the cinema
23213 Black is my favourite colour
35455 I am going to the cinema with you
421323 My friends think I am a good guy.

看来要求是将每个句子与其他句子进行比较。鉴于这里的整体方法,我认为没有一个好的答案。您正在查看 n^2 个比较。随着您的行数变大,整体处理要求会很快变成一个怪物。

为了弄清楚可行性,您可以 运行 一些较小的测试来计算该测试的 n^2 以获得每秒评估行数指标。然后为您要执行的大数据集计算 n^2,以了解所需的处理时间。那是假设您的内存可以处理它。也许已经完成了处理 n^2 问题的工作。可能想四处寻找类似的东西。

您所做的工作是您需要做的工作的两倍多。你将所有事物与所有事物进行两次比较,并与自身进行比较。但即便如此,当事情变大时,如果你只是进行组合,n(n-1)/2 仍然是巨大的。