Как сгруппировать категории в переменную, используя numpy и словарь - PullRequest
0 голосов
/ 23 апреля 2019

Я хочу сгруппировать несколько категорий в переменную панд, используя numpy.where и словарь.

В настоящее время я пытаюсь сделать это, используя просто numpy.where, который значительно увеличивает мой код, если у меня много категорий.Я хочу создать карту, используя словарь, а затем использовать эту карту в numpy.where.

Пример фрейма данных:

dataF = pd.DataFrame({'TITLE':['CEO','CHIEF EXECUTIVE','EXECUTIVE OFFICER','FOUNDER',
                 'CHIEF OP','TECH OFFICER','CHIEF TECH','VICE PRES','PRESIDENT','PRESIDANTE','OWNER','CO OWNER',
                 'DIRECTOR','MANAGER',np.nan]})
dataF
    TITLE
0   CEO
1   CHIEF EXECUTIVE
2   EXECUTIVE OFFICER
3   FOUNDER
4   CHIEF OP
5   TECH OFFICER
6   CHIEF TECH
7   VICE PRES
8   PRESIDENT
9   PRESIDANTE
10  OWNER
11  CO OWNER
12  DIRECTOR
13  MANAGER
14  NaN

Операция Numpy

dataF['TITLE_GRP'] = np.where(dataF['TITLE'].isna(),'NOTAVAILABLE',
                     np.where(dataF['TITLE'].str.contains('CEO|CHIEF EXECUTIVE|EXECUTIVE OFFICER|FOUN'),'CEO_FOUNDER',
                     np.where(dataF['TITLE'].str.contains('CHIEF|OFFICER|^CFO$|^COO$|^CIO$|^CTO$|^CMO$'),'OTHER_OFFICERS',
                     np.where(dataF['TITLE'].str.contains('VICE|VP'),'VP',
                     np.where(dataF['TITLE'].str.contains('PRESIDENT|PRES'),'PRESIDENT',
                     np.where(dataF['TITLE'].str.contains('OWNER'),'OWNER_CO_OWN',
                     np.where(dataF['TITLE'].str.contains('MANAGER|GM|MGR|MNGR|DIR|HEAD|CHAIR'),'DIR_MGR_HEAD'
                     ,dataF['TITLE'])))))))

Преобразованные данные

    TITLE   TITLE_GRP
0   CEO CEO_FOUNDER
1   CHIEF EXECUTIVE CEO_FOUNDER
2   EXECUTIVE OFFICER   CEO_FOUNDER
3   FOUNDER CEO_FOUNDER
4   CHIEF OP    OTHER_OFFICERS
5   TECH OFFICER    OTHER_OFFICERS
6   CHIEF TECH  OTHER_OFFICERS
7   VICE PRES   VP
8   PRESIDENT   PRESIDENT
9   PRESIDANTE  PRESIDENT
10  OWNER   OWNER_CO_OWN
11  CO OWNER    OWNER_CO_OWN
12  DIRECTOR    DIR_MGR_HEAD
13  MANAGER DIR_MGR_HEAD
14  NaN NOTAVAILABLE

Что я хочу сделать, это создать какое-то отображение, как показано ниже:

TITLE_REPLACE = {'CEO_FOUNDER':'CEO|CHIEF EXECUTIVE|EXECUTIVE OFFICER|FOUN',
                'OTHER_OFFICERS':'CHIEF|OFFICER|^CFO$|^COO$|^CIO$|^CTO$|^CMO$',
                'VP':'VICE|VP',
                'PRESIDENT':'PRESIDENT|PRES',
                'OWNER_CO_OWN':'OWNER',
                'DIR_MGR_HEAD':'MANAGER|GM|MGR|MNGR|DIR|HEAD|CHAIR'}

И затем передать его какой-то функции, которая применяет пошаговую операцию с фрагментами и дает мнетот же результат, что и выше.

Я делаю это, я должен параметризовать свой код таким образом, чтобы все параметры для обработки данных были предоставлены из файла json.

Я пробовал панд.заменить, так как он имеет возможность словаря, но он не сохраняет структуру hiercichal, как это сделано во вложенном np.where, он также не может заменить весь заголовок, поскольку он просто заменяет строку, когда находит совпадение.

В случаеВы можете предложить решение, описанное выше. Я также хотел бы знать, как решить следующие 2 других сценария:

  1. Этот сценарий содержит операцию .isin вместо регулярных выражений
dataF['INDUSTRY'] = np.where(dataF['INDUSTRY'].isin(['AEROSPACE','AGRICULTURE/MINING','EDUCATION','ENERGY']),'AER_AGR_MIN_EDU_ENER',
                    np.where(dataF['INDUSTRY'].isin(['TRAVEL','INSURANCE','GOVERNMENT','FINANCIAL SERVICES','AUTO','PHARMACEUTICALS']),'TRA_INS_GOVT_FIN_AUT_PHAR',
                    np.where(dataF['INDUSTRY'].isin(['BUSINESS GOODS/SERVICES','CHEMICALS ','TELECOM','TRANSPORTATION']),'BS_CHEM_TELE_TRANSP',
                    np.where(dataF['INDUSTRY'].isin(['CONSUMER GOODS','ENTERTAINMENT','FOOD AND BEVERAGE','HEALTHCARE','INDUSTRIAL/MANUFACTURING','TECHNOLOGY']),'CG_ENTER_FB_HLTH_IND_TECH',
                    np.where(dataF['INDUSTRY'].isin(['ADVERTISING','ASSOCIATION','CONSULTING/ACCOUNTING','PUBLISHING/MEDIA','TECHNOLOGY']),'ADV_ASS_CONS_ACC_PUBL_MED_TECH',
                    np.where(dataF['INDUSTRY'].isin(['RESTAURANT','SOFTWARE']),'REST_SOFT',
                                            'NOTAVAILABLE'))))))
Этот сценарий содержит операцию .between
dataF['annual_revn'] = np.where(dataF['annual_revn'].between(1000000,10000000),'1_10_MILLION',
                       np.where(dataF['annual_revn'].between(10000000,15000000),'10_15_MILLION',
                       np.where(dataF['annual_revn'].between(15000000,20000000),'15_20_MILLION',
                       np.where(dataF['annual_revn'].between(20000000,50000000),'20_50_MILLION',
                       np.where(dataF['annual_revn'].between(50000000,1000000000),'50_1000_MILLION',
                                           'NOTAVAILABLE_OUTLIER')))))

1 Ответ

0 голосов
/ 23 апреля 2019

Приведенный ниже метод работает, но он не особенно элегантен и может быть не таким быстрым.

import pandas as pd
import numpy as np
import re

dataF = pd.DataFrame({'TITLE':['CEO','CHIEF EXECUTIVE','EXECUTIVE OFFICER','FOUNDER',
                 'CHIEF OP','TECH OFFICER','CHIEF TECH','VICE PRES','PRESIDENT','PRESIDANTE','OWNER','CO OWNER',
                 'DIRECTOR','MANAGER',np.nan]})

TITLE_REPLACE = {'CEO_FOUNDER':'CEO|CHIEF EXECUTIVE|EXECUTIVE OFFICER|FOUN',
                'OTHER_OFFICERS':'CHIEF|OFFICER|^CFO$|^COO$|^CIO$|^CTO$|^CMO$',
                'VP':'VICE|VP',
                'PRESIDENT':'PRESIDENT|PRES',
                'OWNER_CO_OWN':'OWNER',
                'DIR_MGR_HEAD':'MANAGER|GM|MGR|MNGR|DIR|HEAD|CHAIR'}

# Swap the keys and values from the raw data, and split regex by '|'
reverse_replace = {}
for key, value in TITLE_REPLACE.items():
    for value_single in value.split('|'):
        reverse_replace[value_single] = key

def mapping_func(x):
    if not x is np.nan:
        for key, value in reverse_replace.items():
            if re.compile(key).search(x):
                return value
    return 'NOTAVAILABLE'

dataF['TITLE_GRP'] = dataF['TITLE'].apply(mapping_func)


                TITLE       TITLE_GRP
0                 CEO     CEO_FOUNDER
1     CHIEF EXECUTIVE     CEO_FOUNDER
2   EXECUTIVE OFFICER     CEO_FOUNDER
3             FOUNDER     CEO_FOUNDER
4            CHIEF OP  OTHER_OFFICERS
5        TECH OFFICER  OTHER_OFFICERS
6          CHIEF TECH  OTHER_OFFICERS
7           VICE PRES              VP
8           PRESIDENT       PRESIDENT
9          PRESIDANTE       PRESIDENT
10              OWNER    OWNER_CO_OWN
11           CO OWNER    OWNER_CO_OWN
12           DIRECTOR    DIR_MGR_HEAD
13            MANAGER    DIR_MGR_HEAD
14                NaN    NOTAVAILABLE

Для вашего дополнительного сценария может иметь смысл построить df с данными отраслевого отображения, а затем выполнить df.merge, чтобы определить группировку по отрасли

...