Python으로 주민등록인구 데이터 조회하기

Python 라이브러리 PublicDataReader를 이용하면 최신 지역별 주민등록인구 데이터를 쉽게 가져올 수 있다. 해당 데이터는 국가통계포털(KOSIS) 웹 사이트에 접속해 직접 조회할 수도 있지만, KOSIS 공유서비스 Open API를 이용해서도 조회할 수 있다. PublicDataReader는 KOSIS 공유서비스 Open API의 데이터 조회 기능을 포함하고 있어, 이를 활용하면 원하는 데이터를 쉽게 찾고 조회할 수 있다. KOSIS 공유서비스 Open API 신청 방법과 PublicDataReader에서 제공하는 KOSIS 공유서비스 Open API의 모든 기능을 살펴보려면 Python으로 KOSIS 데이터 조회하기를 참고하면 된다. 여기서는 주민등록인구 데이터를 조회하는 방법을 다루기로 한다.


라이브러리 임포트하기

위에서 설치한 PublicDataReader를 임포트한 후 발급받은 KOSIS 공유서비스 Open API 사용자 인증키를 apiKey의 값으로 할당한다.

import PublicDataReader as pdr
print(pdr.__version__)

# KOSIS 공유서비스 Open API 사용자 인증키
apiKey = "사용자 인증키"
1.0.2


조회할 데이터 찾기

Kosis를 이용해 KOSIS 통합검색 기능을 사용할 수 있는 인스턴스인 kosis_search를 만든다. searchNm에는 조회할 데이터를 찾기 위한 키워드를 입력한다. get_data에 의해 반환된 데이터프레임에서 조회할 데이터를 찾아 기관코드ORG_ID통계표IDTBL_ID 값을 확인한다. ‘행정구역(읍면동)별/5세별 주민등록인구(2011년~)’ 데이터의 기관코드101이고, 통계표IDDT_1B04005N 이므로 이 값들을 데이터 조회 시 사용하기 위해 복사해둔다.

# KOSIS 공유서비스 Open API 인스턴스 생성
serviceName = "KOSIS통합검색"
kosis_search = pdr.Kosis(apiKey, serviceName)

# 파라미터
searchNm = "읍면동 주민등록 인구"

# 데이터 조회
df = kosis_search.get_data(searchNm=searchNm)
df.head()
ORG_ID ORG_NM TBL_ID TBL_NM STAT_ID STAT_NM VW_CD MT_ATITLE FULL_PATH_ID CONTENTS STRT_PRD_DE END_PRD_DE ITEM03 REC_TBL_SE TBL_VIEW_URL LINK_URL STAT_DB_CNT QUERY
0 101 행정안전부 DT_1B04005N 행정구역(읍면동)별/5세별 주민등록인구(2011년~) 2008001 주민등록인구현황 MT_ZTITLE 인구 > 주민등록인구현황 A > A_7 행정구역(동읍면)별 5세별 총인구수 남자인구수 여자인구수 전국 서울특별시 종로구 청... 2011 2022 * 주민등록 연령별 인구통계는 주민등록 신고에 따른 것으로 실제 연령과는 차이가 있... N https://kosis.kr/statisticsList/statisticsList... http://kosis.kr/statHtml/statHtml.do?orgId=101... 542 읍면동 주민등록 인구
1 101 통계청 INH_1IN1503_01 인구총조사 인구(시도/시/군/구) 1962001 인구총조사 MT_GTITLE01 주제별 > 인구 101 행정구역별(읍면동) 총인구(명) 전국 동부 읍부 면부 서울특별시 종로구 중구 용산구... 2015 2021 ■ 자료제공처: 통계청 통계정책과 □ 참고사항 - 주민등록에 의한 인구와는 차이가 ... N https://kosis.kr/statisticsList/statisticsList... http://kosis.kr/statHtml/statHtml.do?orgId=101... 542 읍면동 주민등록 인구
2 101 행정안전부 DT_1B04005 행정구역(읍면동)별/5세별 주민등록인구 2008001 주민등록인구현황 MT_ZTITLE 인구 > 주민등록인구현황 A > A_7 행정구역(동읍면)별 5세별 인구 남 여 전국 서울특별시 종로구 청운동 청운효자동 효... 1992 2010 행정안전부 02-2100-3825(전국 주민등록인구현황) 주민등록에 의한 집계(연말... N https://kosis.kr/statisticsList/statisticsList... http://kosis.kr/statHtml/statHtml.do?orgId=101... 542 읍면동 주민등록 인구
3 101 서울특별시 INH_1B04005_11 서울특별시(읍면동)별/5세별 주민등록인구 MT_OTITLE13 시도통계 MT_ZTITLE 지역통계 > 인구 및 사회(사회조사 외) > 서울특별시 > 주민등록인구통계 V > V_3 > V_3_201 > 201_20103 행정구역(동읍면)별 5세별 인구 남 여 서울특별시 종로구 청운동 청운효자동 효자동 ... 1992 2010 DT_1B04005 (행정구역(읍면동)별/5세별 주민등록인구(2011년~))에서 서... N https://kosis.kr/statisticsList/statisticsList... http://kosis.kr/statHtml/statHtml.do?orgId=101... 542 읍면동 주민등록 인구
4 617 경기도 평택시 DT_61701_B000016 주민등록 세대 및 인구 MT_OTITLE12 시군구기본통계 MT_ZTITLE 지역통계 > 지자체 기본통계 > 경기도 > 경기도평택시기본통계 > 인구 V > V_1 > V_1_210 > 210_210A_617_61701 > 210_2... 읍면동별 세대및인구현황별 주민등록 세대 및 인구 팽성읍 안중읍 포승읍 진위면 서탄면... 2013 2020 자료 : 민원행정과 N https://kosis.kr/statisticsList/statisticsList... http://kosis.kr/statHtml/statHtml.do?orgId=617... 542 읍면동 주민등록 인구


데이터 수록 주기와 시점 확인

Kosis를 이용해 통계표 설명 기능을 사용할 수 있는 인스턴스인 kosis_desc를 만든다. 상세기능 detailServiceName의 값으로 ‘자료갱신일’을 입력하고, 위에서 복사해둔 기관코드 orgId와 통계표ID tblId의 값들을 get_data의 인자로 입력하여 데이터 수록 주기와 시점을 확인한다. 수록주기(PRD_SE) 별 최근 수록시점(PRD_DE) 값을 조회하면 수록주기가 년인 경우는 2021년, 수록주기가 월인 경우는 2022년 9월이 최신 데이터임을 알 수 있다.

# KOSIS OPEN API 인스턴스 생성
serviceName = "통계표설명"
kosis_desc = pdr.Kosis(apiKey, serviceName)

# 파라미터
detailServiceName = "자료갱신일"
orgId = "101"
tblId = "DT_1B04005N"

# 데이터 조회
df = kosis_desc.get_data(orgId=orgId, tblId=tblId, detailServiceName=detailServiceName)
df.groupby(by=['PRD_SE']).agg({"PRD_DE": ["min", "max"]})
PRD_DE
min max
PRD_SE
2011 2021
201207 202209


데이터 항목 및 분류 확인하기

Kosis를 이용해 통계표 설명 기능을 사용할 수 있는 인스턴스인 kosis_desc를 만든다. 상세기능 detailServiceName의 값으로 ‘분류항목’을 입력하고, 이번에도 기관코드와 통계표ID를 get_data의 인자로 입력해 결과를 확인한다. OBJ_ID 는 분류ID로 이 값이 ‘ITEM’ 이면 항목을 뜻하고, ITM_ID 값을 통계자료 조회 시 itmId 값으로 입력한다. OBJ_ID 값이 ITEM 이 아니고, OBJ_ID_SN 값에 숫자가 입력되어 있는 경우 이는 분류를 뜻하고, OBJ_ID_SN 의 숫자 값이 분류 수준을 뜻한다. 예를 들어, OBJ_ID 값이 A이고, OBJ_ID_SN 값이 1이라면, ITM_ID 값을 통계자료 조회 시 objL1의 값으로 입력한다.

# 파라미터
detailServiceName = "분류항목"
orgId = "101"
tblId = "DT_1B04005N"

# 데이터 조회
item = kosis_desc.get_data(orgId=orgId, tblId=tblId, detailServiceName=detailServiceName)

통계표 조회 시 항목은 총인구수, 남자인구수 그리고 여자인구수 모두 사용하기로 한다. ITM_ID의 값인 T2, T3 그리고 T4를 모두 복사해둔다.

item.loc[item["OBJ_ID"]=="ITEM"]
ITM_NM TBL_ID ITM_NM_ENG ITM_ID OBJ_NM OBJ_NM_ENG ORG_ID OBJ_ID OBJ_ID_SN UP_ITM_ID
0 총인구수 DT_1B04005N Population T2 항목 Item code list 101 ITEM NaN NaN
1 남자인구수 DT_1B04005N Male T3 항목 Item code list 101 ITEM NaN NaN
2 여자인구수 DT_1B04005N Female T4 항목 Item code list 101 ITEM NaN NaN

분류1의 경우 전체 선택하기로 한다. ITM_ID를 일부 선택하려면 ‘00 11 11110’ 과 같이 입력해야 하지만, 전체 선택의 경우 ‘ALL’ 이라고 입력해도 된다. 여기에서는 종류가 많으므로 직접 값을 복사하지 않고 넘어간다.

item.loc[item["OBJ_ID"]=="A"]
ITM_NM TBL_ID ITM_NM_ENG ITM_ID OBJ_NM OBJ_NM_ENG ORG_ID OBJ_ID OBJ_ID_SN UP_ITM_ID
3 전국 DT_1B04005N Whole country 00 행정구역(동읍면)별 By Administrative District 101 A 1 NaN
4 서울특별시 DT_1B04005N Seoul 11 행정구역(동읍면)별 By Administrative District 101 A 1 NaN
5 종로구 DT_1B04005N Jongno-gu 11110 행정구역(동읍면)별 By Administrative District 101 A 1 11
6 청운효자동 DT_1B04005N Cheongunhyoja-dong 1111051500 행정구역(동읍면)별 By Administrative District 101 A 1 11110
7 사직동 DT_1B04005N Sajik-dong 1111053000 행정구역(동읍면)별 By Administrative District 101 A 1 11110
... ... ... ... ... ... ... ... ... ... ...
4181 서홍동 DT_1B04005N Seohong-dong 5013058000 행정구역(동읍면)별 By Administrative District 101 A 1 50130
4182 대륜동 DT_1B04005N Daeryun-dong 5013059000 행정구역(동읍면)별 By Administrative District 101 A 1 50130
4183 대천동 DT_1B04005N Daecheon-dong 5013060000 행정구역(동읍면)별 By Administrative District 101 A 1 50130
4184 중문동 DT_1B04005N Jungmun-dong 5013061000 행정구역(동읍면)별 By Administrative District 101 A 1 50130
4185 예래동 DT_1B04005N Yerae-dong 5013062000 행정구역(동읍면)별 By Administrative District 101 A 1 50130

4183 rows × 10 columns

분류2의 경우 연령별 구분은 사용하지 않고 총계만 조회하기로 한다. 따라서 ITM_ID 값이 0인 경우만 해당하므로 0을 복사해둔다.

item.loc[item["OBJ_ID"]=="B"]
ITM_NM TBL_ID ITM_NM_ENG ITM_ID OBJ_NM OBJ_NM_ENG ORG_ID OBJ_ID OBJ_ID_SN UP_ITM_ID
4186 DT_1B04005N Total 0 5세별 By Age Group (Five-Year) 101 B 2 NaN
4187 0 - 4세 DT_1B04005N 0-4 Years old 5 5세별 By Age Group (Five-Year) 101 B 2 NaN
4188 5 - 9세 DT_1B04005N 5-9 Years old 10 5세별 By Age Group (Five-Year) 101 B 2 NaN
4189 10 - 14세 DT_1B04005N 10-14 Years old 15 5세별 By Age Group (Five-Year) 101 B 2 NaN
4190 15 - 19세 DT_1B04005N 15-19 Years old 20 5세별 By Age Group (Five-Year) 101 B 2 NaN
4191 20 - 24세 DT_1B04005N 20-24 Years old 25 5세별 By Age Group (Five-Year) 101 B 2 NaN
4192 25 - 29세 DT_1B04005N 25-29 Years old 30 5세별 By Age Group (Five-Year) 101 B 2 NaN
4193 30 - 34세 DT_1B04005N 30-34 Years old 35 5세별 By Age Group (Five-Year) 101 B 2 NaN
4194 35 - 39세 DT_1B04005N 35-39 Years old 40 5세별 By Age Group (Five-Year) 101 B 2 NaN
4195 40 - 44세 DT_1B04005N 40-44 Years old 45 5세별 By Age Group (Five-Year) 101 B 2 NaN
4196 45 - 49세 DT_1B04005N 45-49 Years old 50 5세별 By Age Group (Five-Year) 101 B 2 NaN
4197 50 - 54세 DT_1B04005N 50-54 Years old 55 5세별 By Age Group (Five-Year) 101 B 2 NaN
4198 55 - 59세 DT_1B04005N 55-59 Years old 60 5세별 By Age Group (Five-Year) 101 B 2 NaN
4199 60 - 64세 DT_1B04005N 60-64 Years old 65 5세별 By Age Group (Five-Year) 101 B 2 NaN
4200 65 - 69세 DT_1B04005N 65-69 Years old 70 5세별 By Age Group (Five-Year) 101 B 2 NaN
4201 70 - 74세 DT_1B04005N 70-74 Years old 75 5세별 By Age Group (Five-Year) 101 B 2 NaN
4202 75 - 79세 DT_1B04005N 75-79 Years old 80 5세별 By Age Group (Five-Year) 101 B 2 NaN
4203 80 - 84세 DT_1B04005N 80-84 Years old 85 5세별 By Age Group (Five-Year) 101 B 2 NaN
4204 85 - 89세 DT_1B04005N 85-89 Years old 90 5세별 By Age Group (Five-Year) 101 B 2 NaN
4205 90 - 94세 DT_1B04005N 90-94 Years old 95 5세별 By Age Group (Five-Year) 101 B 2 NaN
4206 95 - 99세 DT_1B04005N 95-99 Years old 100 5세별 By Age Group (Five-Year) 101 B 2 NaN
4207 100+ DT_1B04005N 100 Years old & over 105 5세별 By Age Group (Five-Year) 101 B 2 NaN


통계표 조회하기

Kosis를 이용해 통계자료 기능을 사용할 수 있는 인스턴스인 kosis_data를 만든다. 행정구역(읍면동)별/5세별 주민등록인구(2011년~) 통계표를 조회를 위해 위에서 복사해둔 값들을 순서대로 get_data의 인자로 입력해준다. itmId의 값으로 모든 항목값을 입력했지만, objL1과 같이 ‘ALL’이라고 입력해도 전체 선택이 된다.

# KOSIS OPEN API 인스턴스 생성
serviceName = "통계자료"
kosis_data = pdr.Kosis(apiKey, serviceName)

# 파라미터
orgId = "101"             # 기관코드
tblId = "DT_1B04005N"     # 통계표ID
objL1 = "ALL"             # 분류1 - 전체 선택
objL2 = "0"               # 분류2 - `계` 선택
itmId = "T2 T3 T4"        # 항목 - '총인구수', '남자인구수' 그리고 '여자인구수' 선택
prdSe = "M"               # 수록주기 - `1개월 주기` 선택
startPrdDe = "202209"     # 시작수록시점 (YYYYMM)
endPrdDe = "202209"       # 종료수록시점 (YYYYMM)

# 데이터 조회
df = kosis_data.get_data(orgId=orgId, tblId=tblId, objL1=objL1, objL2=objL2, itmId=itmId, prdSe=prdSe, startPrdDe=startPrdDe, endPrdDe=endPrdDe)
df.head()
TBL_NM PRD_DE TBL_ID ITM_NM ITM_NM_ENG ITM_ID UNIT_NM ORG_ID UNIT_NM_ENG C1_OBJ_NM C1_OBJ_NM_ENG C2_OBJ_NM C2_OBJ_NM_ENG DT PRD_SE C2 C1 C1_NM C2_NM C1_NM_ENG C2_NM_ENG
0 행정구역(읍면동)별/5세별 주민등록인구(2011년~) 202209 DT_1B04005N 총인구수 Population T2 101 Person 행정구역(동읍면)별 By Administrative District 5세별 By Age Group (Five-Year) 51466658 M 0 00 전국 Whole country Total
1 행정구역(읍면동)별/5세별 주민등록인구(2011년~) 202209 DT_1B04005N 남자인구수 Male T3 101 Person 행정구역(동읍면)별 By Administrative District 5세별 By Age Group (Five-Year) 25653998 M 0 00 전국 Whole country Total
2 행정구역(읍면동)별/5세별 주민등록인구(2011년~) 202209 DT_1B04005N 여자인구수 Female T4 101 Person 행정구역(동읍면)별 By Administrative District 5세별 By Age Group (Five-Year) 25812660 M 0 00 전국 Whole country Total
3 행정구역(읍면동)별/5세별 주민등록인구(2011년~) 202209 DT_1B04005N 총인구수 Population T2 101 Person 행정구역(동읍면)별 By Administrative District 5세별 By Age Group (Five-Year) 9450768 M 0 11 서울특별시 Seoul Total
4 행정구역(읍면동)별/5세별 주민등록인구(2011년~) 202209 DT_1B04005N 남자인구수 Male T3 101 Person 행정구역(동읍면)별 By Administrative District 5세별 By Age Group (Five-Year) 4582361 M 0 11 서울특별시 Seoul Total


피벗 테이블 만들기

통계표 조회 결과를 아래와 같이 원하는 형태로 재구조화하여 분석 목적에 맞게 사용하면 된다.

pv = df.pivot(index=["C1","C1_NM","PRD_DE"], columns=["ITM_NM"], values="DT").reset_index()
pv.columns.name = None
pv['PRD_DE'] = pd.to_datetime(pv['PRD_DE'], format="%Y%m")
numCols = ["남자인구수","여자인구수","총인구수"]
for col in numCols:
    pv[col] = pd.to_numeric(pv[col])
pv
C1 C1_NM PRD_DE 남자인구수 여자인구수 총인구수
0 00 전국 2022-09-01 25653998 25812660 51466658
1 11 서울특별시 2022-09-01 4582361 4868407 9450768
2 11110 종로구 2022-09-01 68652 73326 141978
3 1111051500 청운효자동 2022-09-01 5356 6337 11693
4 1111053000 사직동 2022-09-01 4037 5089 9126
... ... ... ... ... ... ...
3853 5013058000 서홍동 2022-09-01 5569 5683 11252
3854 5013059000 대륜동 2022-09-01 7854 7695 15549
3855 5013060000 대천동 2022-09-01 7018 6826 13844
3856 5013061000 중문동 2022-09-01 6210 6033 12243
3857 5013062000 예래동 2022-09-01 1992 1916 3908

3858 rows × 6 columns


참고

댓글남기기