Сопоставьте значение нового столбца путем поиска в другом фрейме данных - PullRequest
1 голос
/ 29 мая 2020

У меня есть два фрейма данных: df_geo и df_event. Я хочу создать два новых столбца в df_event. Фреймы данных выглядят следующим образом, хотя дополнительные столбцы были удалены для простоты:

data_geo =  [['040','01','000','00000','00000','00000','Alabama'],
             ['050','01','001','00000','00000','00000','Autauga County'],
             ['050','01','097','00000','00000','00000','Mobile County'],
             ['050','01','101','00000','00000','00000','Montgomery County'],
             ['050','01','115','00000','00000','00000','St. Clair County'],
             ['040','09','000','00000','00000','00000','Connecticut'],
             ['061','09','001','04720','00000','00000','Bethel town'],
             ['040','17','000','00000','00000','00000','Illinois'],
             ['061','17','109','05638','00000','00000','Bethel township'],
             ['050','17','163','00000','00000','00000','St. Clair County']] 

dfgeo = pd.DataFrame(data_geo, columns = ['summary_level', 'state_fips','county_fips','subdivision_code_fips','place_code_fips','city_code_fips','area_name']) 

df_geo.info()

RangeIndex: 43847 entries, 0 to 43846
Data columns (total 7 columns):
summary_level            43847 non-null object
state_fips               43847 non-null object
county_fips              43847 non-null object
subdivision_code_fips    43847 non-null object
place_code_fips          43847 non-null object
city_code_fips           43847 non-null object
area_name                43847 non-null object
data_event = [['event_id','_','Alabama'], 
              ['event_id','_','Connecticut'],
              ['event_id','Autauga County','Alabama'],
              ['event_id','Fairfield County','Connecticut'],
              ['event_id','Fairbanks North Star Borough','Alaska']] 

df_event = pd.DataFrame(data_event, columns = ['event_id','county','state']) 

df_event.info()

RangeIndex: 1261 entries, 0 to 1260
Data columns (total 3 columns):
event_id                1261 non-null object
county                   999 non-null object
state                   1261 non-null object
dtypes: object(3) 

GOAL для создания функции, которая может принимать county и state входы из df_event и для создания двух новых столбцов в одном фрейме данных. Новые столбцы основаны на значениях state_fips и county_fips в df_geo. Пример этого может выглядеть следующим образом:

inputA fun('df_geo','Connecticut','Fairfield County'):   

resultA = ['event_id','Connecticut','Fairfield County','09','001']
                                                       ^New columns

inputB fun('df_geo','Alaska','Fairbanks North Star Borough'):   

resultB = ['event_id','Alaska','Fairbanks North Star Borough','02','090']
                                                              ^New columns

Это ПРОБЛЕМА , потому что мне также нужно использовать эту функцию в списке из 1200 (и растущих) событий, функция будет должны работать в рамках функции lamba или чего-то еще, что может отображать ее по всему фрейму данных.

Это усложняется идентичными названиями округов, такими как "St. Clair County", которые встречаются в нескольких штатах. Хотя их area_names идентичны, значение state_fips будет другим.

state_fips Сент-Клер, Иллинойс, это 17 , то же самое, что и во всех других округах Иллинойса и в самом штате. state_fips Сент-Клер, Алабама, это 01 , то же самое, что и все другие округа в Алабаме, и так далее ...

Я хотел бы использовать ту же функцию поиска и карты вплоть до city_code_fips. На этом уровне любые поисковые запросы должны быть точно такими же, чтобы я не выбрал «город Вефиль», когда я собираюсь найти «городок Вефиля». Точные входные данные также важны, потому что в некоторых штатах, таких как Луизиана, географические регионы уровня графства называются другим именем.

В df_event знак '_' указывает, что округ неизвестен.

df_event['event_id'] - уникальная строка. Во фрейме данных есть строки, которые почти идентичны, но с разными идентификаторами, указывающими на то, что событие произошло несколько раз. Это не влияет на. state_fips или county_fips.

Я знаю, что это многоэтапный процесс, но вся помощь приветствуется. Спасибо.

Ответы [ 2 ]

1 голос
/ 29 мая 2020

Вы можете сделать это, используя df.merge:

In [289]: df_event['state_fips'] = df_event.merge(dfgeo[['state_fips','area_name']], left_on='state', right_on='area_name', how='left')['state_fips']    
In [290]: df_event['county_fips'] = df_event.merge(dfgeo[['county_fips','area_name']], left_on='county', right_on='area_name', how='left')['county_fips']

In [291]: df_event
Out[291]: 
  unique_str                        county        state state_fips county_fips
0   Event Id                             _      Alabama         01         NaN
1   Event Id                             _  Connecticut         09         NaN
2   Event Id                Autauga County      Alabama         01         001
3   Event Id              Fairfield County  Connecticut         09         001
4   Event Id  Fairbanks North Star Borough       Alaska         02         090
0 голосов
/ 29 мая 2020

Если есть дубликаты в столбце area_name, сначала удалите их, набрав DataFrame.drop_duplicates:

dfgeo = dfgeo.drop_duplicates('area_name')

А затем Series.map, что такое быстрее, как merge, поэтому предпочтительнее:

df_event['state_fips'] = df_event['state'].map(dfgeo.set_index('area_name')['state_fips'])
df_event['county_fips'] = df_event['county'].map(dfgeo.set_index('area_name')['county_fips'])
print (df_event)
  unique_str                        county        state state_fips county_fips
0   Event Id                             _      Alabama         01         NaN
1   Event Id                             _  Connecticut         09         NaN
2   Event Id                Autauga County      Alabama         01         001
3   Event Id              Fairfield County  Connecticut         09         001
4   Event Id  Fairbanks North Star Borough       Alaska         02         090
...