Найдите подходящую строку между двумя фреймами данных и назначьте имя соответствующего столбца для другого фрейма данных с помощью функции (Pandas) - PullRequest
0 голосов
/ 09 января 2019

«unique_receivers» - это фрейм данных Pandas со столбцами для уникальных получателей транзакций, суммами и пустым столбцом для категорий, которые я хочу заполнить функцией.

unique_receivers

    Receiver    Amount  Category
144 SALE        -18.93  
141 TACO BELL   -19.20  
78  MCDONALDS   -19.65  
104 EXPRESS     -20.00  
154 SHOP        -24.00  

Я хочу заполнить столбец "Категория" указанного выше фрейма данных на основе совпадений его столбца "Получатель" с условиями поиска в другом фрейме данных, "category_searchterms".

"category_searchterms" содержит категории в качестве имен столбцов, а столбец каждой категории имеет соответствующие условия поиска.

Вот пример этого кадра данных:

categories

    Groceries   Electricity Fastfood
0   SHOP        ELCOMPANY   MCDONALDS
1   MARKET      POWER       SUBWAY
2   SALE                    PIZZA       

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

Я пытаюсь сделать это с помощью этой функции:

def add_category(searchterm):
    unique_receivers["Category"] = (category_searchterms == searchterm).any().idxmax()

А потом назовите это:

unique_receivers.apply(add_category(unique_receivers["Receiver"]), axis=1)

Проблема:

TypeError: ("'NoneType' object is not callable", 'occurred at index 144')

Индекс 144 - это первая строка в "unique_receivers". Если я сейчас вызову фрейм данных, каждая строка будет заполнена первой категорией:

unique_receivers

    Receiver    Amount  Category
144 SALE        -18.93  Groceries   
141 TACO BELL   -19.20  Groceries   
78  MCDONALDS   -19.65  Groceries   
104 EXPRESS     -20.00  Groceries   
154 SHOP        -24.00  Groceries   

Как я могу заставить реально подходящую категорию отображаться в столбце "Категория" каждой строки? Спасибо.

Ответы [ 2 ]

0 голосов
/ 09 января 2019

Вот способ использования apply и пользовательской функции lambda:

unique_receivers['Category'] = unique_receivers.Receiver.apply(lambda x:
                               ''.join([i for i in categories.columns 
                               if categories.loc[:,i].str.contains(x).any()]) 
                               or None)

 Receiver  Amount   Category
144       SALE  -18.93  Groceries
141   TACOBELL  -19.20       None
78   MCDONALDS  -19.65   Fastfood
104    EXPRESS  -20.00       None
154       SHOP  -24.00  Groceries

Или используя pd.melt и вправо merge с df1:

categories.melt(var_name='Category').merge(unique_receivers, 
                                           left_on='value', right_on='Receiver',
                                           how='right')\
                                           [['Receiver','Amount','Category']]

    Receiver  Amount   Category
0       SHOP  -24.00  Groceries
1       SALE  -18.93  Groceries
2  MCDONALDS  -19.65   Fastfood
3   TACOBELL  -19.20       None
4    EXPRESS  -20.00       None
0 голосов
/ 09 января 2019

Это работает?

import pandas as pd

unique_receivers['Category'] = unique_receivers['Receivers'].apply(lambda x: pd.np.resize(categories.columns.values[pd.np.where(categories.isin([x]))[1]],1)[0])

np.resize означает, что вы не получите IndexError, если значения не найдены

...