当 fuzz.WRatio > 90 时对所有计数求和,否则保持不变

Sum all counts when their fuzz.WRatio > 90 otherwise leave intact

我想做的实际上是将所有类似的字符串分组在一列中,然后将它们相加 如果有相似性,则相应计数,否则,保留它们。 有点像这个post。不幸的是,我无法将其应用于我的案例:

不幸的是,我完成了以下步骤:

我写了一个函数来打印每行字符串的所有 fuzz.Wratio, 当每一行从顶部开始线性搜索以检查是否有其他类似的 其余行中的字符串。如果 WRatio > 90,我想对这些行求和 相应的计数。否则,将它们留在那里。

我创建了一个如下所示的测试数据:

test_data=pd.DataFrame({
    'name':['Apple.Inc.','apple.inc','APPLE.INC','OMEGA'],
    'count':[4,3,2,6]
})

所以我想做的是将结果作为数据框,例如:

result=pd.Dataframe({
    'Nname':['Apple.Inc.','OMEGA'],
    'Ncount':[9,6]
})

到目前为止,我的函数只给出了每一行的模糊率, 据我了解, 每行与自身比较三次(这里有四行)。 所以我的函数输出看起来像:

pd.Dataframe({
    'Nname':['Apple.Inc.','Apple.Inc.','Apple.Inc.','apple.inc',\
    'apple.inc','apple.inc'],
    'Ncount':[4,4,4,3,3,3],
    'FRatio': [100,100,100,100,100,100] })

这只是我用这个测试数据编写的函数的全部输出的一部分。 最后一行 "OMEGA" 会给我一个大约 18 的模糊比率。

我的函数是这样的:

def checkDupTitle2(data):
    Nname=[]
    Ncount=[]
    f_ratio=[]

    for i in range(0, len(data)):
        current=0
        count=0
        space=0
        for space in range(0, len(data)-1-current):
            ratio=fuzz.WRatio(str(data.loc[i]['name']).strip(), \
                        str(data.loc[current+space]['name']).strip())
            Nname.append(str(data.loc[i]['name']).strip())
            Ncount.append(str(data.loc[i]['count']).strip())
            f_ratio.append(ratio)
            df=pd.DataFrame({
                'Nname': Nname,
                'Ncount': Ncount,
                'FRatio': f_ratio
            })
    return df

所以在 运行 这个函数并得到输出之后, 我试图得到我最终想要的东西。 在这里,我尝试在上面创建的 df 上分组:

output.groupby(output.FRatio>90).sum()

但是这样,我的数据框中仍然需要一个 "name", 我怎样才能决定这个总数的名字,比如这里的 9 个。 "Apple.Inc" 或 "apple.inc" 或 "APPLE.INC"?

或者,我是不是把它弄得太复杂了? 有没有办法一开始就按"name"分组,然后把"Apple.Inc."、"apple.inc"和"APPLE.INC"都一样,那我的问题就解决了。我已经有一段时间了。任何帮助将是高度 赞赏!谢谢!

以下代码使用我的库 RapidFuzz 而不是 FuzzyWuzzy,因为它速度更快,并且它有一个处理方法 extractIndices,这对这里很有帮助。这个解决方案要快一些,但由于我不经常使用 pandas,我确信还有一些可以改进的地方:)

import pandas as pd
from rapidfuzz import process, utils

def checkDupTitle(data):
    values = data.values.tolist()
    companies = [company for company, _ in values]
    pcompanies = [utils.default_process(company) for company in companies]
    counts = [count for _, count in values]

    results = []
    while companies:
        company = companies.pop(0)
        pcompany = pcompanies.pop(0)
        count = counts.pop(0)

        duplicates = process.extractIndices(
            pcompany, pcompanies,
            processor=None, score_cutoff=90, limit=None)

        for (i, _) in sorted(duplicates, reverse=True):
            count += counts.pop(i)
            del pcompanies[i]
            del companies[i]
        results.append([company, count])

    return pd.DataFrame(results, columns=['Nname','Ncount'])

test_data=pd.DataFrame({
    'name':['Apple.Inc.','apple.inc','APPLE.INC','OMEGA'],
    'count':[4,3,2,6]
})

checkDupTitle(test_data)

结果是

pd.Dataframe({
    'Nname':['Apple.Inc.','OMEGA'],
    'Ncount':[9,6]
})