0

我想要做的实际上是按一列中的所有相似字符串分组,如果有相似性,则将它们的相应计数相加,否则,留下它们。有点类似这个帖子。不幸的是,我无法将其应用于我的案例: 如何使用正则表达式匹配按列对 Pandas 数据进行分组

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

我编写了一个函数来打印每行字符串的所有 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]
})

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

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 上尝试了 group by:

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

但是这样一来,我的数据框中仍然需要一个“名称”,我该如何决定这个总数的哪些名称,比如这里的 9 个。“Apple.Inc”或“apple.inc”或“APPLE.INC”?

或者,我是否让它太复杂了?有没有办法一开始就按“名称”分组,然后一视同仁地对待“Apple.Inc.”、“apple.inc”和“APPLE.INC”,那么我的问题就解决了。我已经很长一段时间了。任何帮助将不胜感激!谢谢!

4

1 回答 1

0

下面的代码使用我的库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]
})
于 2020-04-08T17:31:35.317 回答