Суммируйте все подсчеты, когда их fuzz.WRatio> 90 в противном случае оставить без изменений - PullRequest
0 голосов
/ 07 апреля 2020

На самом деле я хотел сгруппировать все одинаковые строки в один столбец и суммировать их соответствующие значения, если есть сходство, в противном случае оставьте их. Немного похоже на этот пост. К сожалению, я не смог применить это в моем случае: Как сгруппировать 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]
})

Моя функция до сих пор дала мне только коэффициент нечеткости для каждой строки, и, насколько я понимаю, каждая строка сравнивается сама с собой три раза (здесь у нас четыре строки). Поэтому вывод моей функции будет выглядеть следующим образом:

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

Так что после запуска этой функции и получения вывода я попытался получить то, что я в конце концов хочу. здесь я попробовал group by на df, созданном выше:

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

Но в этом случае мне все еще нужно «имя» в моем фрейме данных, как я могу решить, какие имена для этого общего числа, скажем, 9 Вот. «Apple.In c» или «apple.in c» или «APPLE.IN C»?

Или я сделал его слишком сложным? Есть ли способ сгруппировать по «имени» в самый первый раз и обработать «Apple.In c.», «Apple.in c» и «APPLE.IN C» одинаково, тогда моя проблема решил. У меня пень довольно давно. Любая помощь будет высоко ценится! Спасибо!

1 Ответ

0 голосов
/ 08 апреля 2020

Следующий код использует мою библиотеку RapidFuzz вместо FuzzyWuzzy, поскольку он быстрее и имеет метод процесса extractIndices, который здесь помогает. Это решение работает немного быстрее, но поскольку я не работаю с pandas regulary, я уверен, что есть еще кое-что, что можно улучшить:)

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]
})
...