Как лучше всего использовать нечеткое определение для сравнения каждого значения столбца со всеми значениями отдельного столбца фрейма данных? - PullRequest
0 голосов
/ 03 августа 2020

У меня действительно тяжелые времена с этим. Скажем, у меня есть два фрейма данных: один с фруктами, а другой с мармеладом. В каждом из фреймов данных есть много других данных. Это выглядит примерно так:

fruit: 

   fruitId  fruitName
0     1     banana
1     2     orange
2     3     apple
3     4     pear
4     5     lemon

candy:

   candyId  candyName         fruitId
0     1     Orange Julius     null
1     2     Bananarama        null
2     3     Sour Lemon Drops  null
3     4     Chocolate Bar     null
4     5     Applicious        null

Мне нужно сопоставить candyName с правильным фруктом, а затем поместить соответствующий fruitId в столбец fruitId фрейма данных candy. Предположим для моих целей, что .contains вообще не работает; в столбце candyName слишком много творческих и явных орфографических ошибок.

Я попытался определить функцию, которая использует нечеткое отображение, а затем использовать это в .map, но я не могу заставить функцию работай. Ему необходимо проверить каждое значение первого df, чтобы увидеть, находится ли оно во втором, а затем перейти к следующему значению et c. Функции, которые я создаю, все время хотят проводить сравнения, где они либо (а) в одном фрейме данных, либо (б) в одной строке.

Я нашел решение этой проблемы, но это уродливо потому что он использует iterrows (), который вы не должны использовать. Вот он:

import pandas as pd
from fuzzywuzzy import fuzz

candy_file = 'candy.csv'
fruit_file = 'fruits.csv'
candy = pd.read_csv(candy_file)
fruit = pd.read_csv(fruit_file)

dict = {}

for i, row1 in candy.iterrows():
    for j, row2 in fruit.iterrows():
        if fuzz.partial_ratio(row1['candyName'], row2['fruitName']) >= 80:
            dict[row1['candyName']] = row2['fruitId']

candy['fruitId'] = candy['candyName'].map(dict)

Это займет вечность. Примерно 10 минут, чтобы пройти 500 строк. Есть лучший способ сделать это? Я написал около сотни различных фрагментов кода для более быстрых функций без каких-либо результатов.

Спасибо!

1 Ответ

1 голос
/ 03 августа 2020

Это медленно, потому что вы сейчас работаете в O (N ^ 2).

Вместо использования iterrows используйте словари для итерации. Это можно сделать с помощью следующего:

candydict = candy.to_dict{}
fruitdict = fruit.to_dict{}

for k,v in candydict.items():
   for k2,v2 in fruitdict.items():
      #do the rest of your comparisons here

Это должно значительно ускорить его.

...