Как добавить столбец pandas на основе частичного совпадения строк? - PullRequest
1 голос
/ 11 июля 2020

У меня есть pandas данные о расходах по кредитной карте различных категорий, которые еще предстоит определить (бензин, продукты, фаст-фуд и т. Д. c.).

df1: 

Category   Date         Description                 Cost 
nan        7.1.20       Chipotle Downtown West      $8.23
nan        7.1.20       Break Time - Springfield    $23.57
nan        7.3.20       State Farm - Agent          $94.23
nan        7.3.20       T-Mobile                    $132.42
nan        7.4.20       Venmo -xj8382dzavvd         $8.00
nan        7.6.20       Broadway McDonald's         $11.73
nan        7.8.20       Break Time - Townsville     $44.23

Я бы хотелось бы поддерживать второй фрейм данных, который ищет ключевые слова в описании и заполняет столбец «Категория». Примерно так:

df2:

item           category
mcdonald       fast food
state farm     insurance
break time     gas
chipotle       fast food
mobile         cell phone 

Идея здесь в том, что я бы написал строки кода для поиска частичных строк в df1['Description'] и заполню df1['Category'] значением из df2[category].

Я уверен, что есть чистый и питонный c способ обработки этого кода, но ниже я могу найти наиболее близкий из них. Ошибочный результат приведенного ниже кода состоит в том, что все строки df1['Category'], содержащие совпадение, устанавливаются на последний l oop в df2 (например, в этом случае для всех строк будет установлено значение «сотовый телефон»).

    for x in df2['item']:
        for y in df2['category']:
            df1['Category'] = np.where(
                        df1['Description'].str.lower().str.contains(x),
                        y,
                        df1['Category'])

Спасибо за помощь!

1 Ответ

1 голос
/ 12 июля 2020

Вы можете сделать это с помощью map, Python встроенной функции diffflib для получения близких совпадений и лямбда-выражения. Вызов difflib возвращает список совпадений строк, и вы можете настроить параметр отсечки для большей или меньшей чувствительности по мере необходимости.

import difflib

# you'll need to change both cutoff values here for the lambda to work correctly

df1['Category'] = df1['Description'].map(lambda x: difflib.get_close_matches(x, df2['item'], cutoff=0.3)[0] if len(difflib.get_close_matches(x, df2['item'], cutoff=0.3)) > 1 else 'no match')

print(df1)


    Category    Date    Description                 Cost
0   chipotle    7.1.20  Chipotle Downtown West      $8.23
1   break time  7.1.20  Break Time - Springfield    $23.57
2   state farm  7.3.20  State Farm - Agent          $94.23
3   mobile      7.3.20  T-Mobile                    $132.42
4   no match    7.4.20  Venmo -xj8382dzavvd         $8.00
5   mcdonald    7.6.20  Broadway McDonald's         $11.73
6   break time  7.8.20  Break Time - Townsville     $44.23
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...