Обновите значение в новый столбец в текущем фрейме данных на основе другого столбца из другого фрейма данных

#python #pandas #dataframe

Вопрос:

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

Примечание : это должно работать независимо от прописных или строчных букв

таблица df1 выглядит следующим образом :

            Messages
0         Firewall_Error
1         Firewall_Error_1
2         Firewall_Error_2
3         Firewall_Error_3
4        Wifihealth_1_Info
              ...         
109       Firewall_Error_1
110       Firewall_Error_2
111       Firewall_Error_3
112      Wifihealth_1_Info
113    Wifihealth_2_Failed
 

Master_df выглядит так :

     Strings Category
0   error   Error
1   info    Information
2   failed  Warning
 

Поэтому, если подстрока Master_df[‘Строки’][0] найдена в столбце Сообщений df1, сопоставьте эту строку в df1[категория] как Master_df[‘Категория’][0] и так далее..

Ожидаемый результат:

df1 должен выглядеть так :

            Messages           category
0         Firewall_Error      Error
1         Firewall_Error_1    Error
2         Firewall_Error_2    Error
3         Firewall_Error_3    Error
4        Wifihealth_1_Info    Information
              ...         
109       Firewall_Error_1    Error
110       Firewall_Error_2    Error
111       Firewall_Error_3    Error
112      Wifihealth_1_Info    Information
113    Wifihealth_2_Failed    warning
 

Коды пытались :

 for i in range(0,len(Master_df['Strings'])):
    df1['Category'] = pd.np.where(df1.Messages.str.contains(Master_df['Strings'][i]), Master_df['Category'][i]))
 

Ответ №1:

Сначала используйте Series.str.lower для нижнего регистра, затем Series.str.extract путем объединения Strings преобразуется в index для возможного сопоставления Series.map с новым столбцом:

 #if need also convert Strings to lowercases
s = Master_df.set_index('Strings')['Category'].rename(index=str.lower)
pat = f'({"|".join(s.index)})'
df1['Category'] = df1['Messages'].str.lower().str.extract(pat, expand=False).map(s)
print (df1)
                Messages     Category
0         Firewall_Error        Error
1       Firewall_Error_1        Error
2       Firewall_Error_2        Error
3       Firewall_Error_3        Error
4      Wifihealth_1_Info  Information
109     Firewall_Error_1        Error
110     Firewall_Error_2        Error
111     Firewall_Error_3        Error
112    Wifihealth_1_Info  Information
113  Wifihealth_2_Failed      Warning
 

Комментарии:

1. Все работает нормально. Хотя, сработает ли это вообще, если случаи в сообщениях противоречивы? потому что я вижу использование lower()..просто запутался в этой операции..

2. @AnandThirtha — Ya, я использую его для сопоставления строчных значений с Master_df['Strings']

3. Что, если мне придется полностью игнорировать чувствительность к регистру? просто сопоставьте строки и карту? потому что при проверке с помощью различных сценариев я обнаружил несколько значений nan, которые не были сопоставлены ..

4. @AnandThirtha — Я добавляю str.ниже для сопоставления большего количества значений, например, если опустить его в образце, данные Firewall_Error не могут совпадать с error — но firewall_error совпадают error . Если у некоторых НАН должна быть какая-то другая проблема

5. Да, кажется, это работает … спасибо.. Таким образом, сообщения могут иметь любой тип.. верхний или нижний регистр ..это должно работать, изменив регистр в самом мастере?