Geopandas분석 (3) 전처리

geopandas 분석방법 (3)

앞서 진행한 좌표변환에 성공한 유동인구(생활인구) 데이터를 시각화하기 위해 하는 전단계 전처리 작업이다. geopandas분석 (2) 좌표변환 를 보고 오길 바란다.

시각화를 위한 전처리 단계

  • 생활인구 데이터를 이용하여 서울시 지도에 총생활인구수의 평균을 색으로 구별할 수 있게 하기위한 전처리이다.
  • 생활인구 데이터는 행정동별, 집계구 별로 되어 있는데 방법은 같아서 행정동을 예시로 보여준다.
  • 변수명 앞에 h_가 있으면 행정동, 없으면 집계구라고 생각하면 된다.

1) 불러올 패키지 및 데이터 로드

import pandas as pd
import json
import geopandas as gpd
from geopandas import GeoDataFrame

생활인구데이터를 불어오고 코드를 통해 Merge 시켜야해서 코드(숫자로 되어있는)를 astype()을 이용하여 str로 변환해준다. Merge는 int로 불가능하기 때문에 이런 작업을 한다.

local=pd.read_csv('LOCAL_PEOPLE_20200513.csv',engine='python', encoding='euc-kr')
code=pd.read_csv("동_코드.csv",engine='python', encoding='euc-kr')

local['행정동코드']=local['행정동코드'].astype(str)
code['행자부행정동코드']=code['행자부행정동코드'].astype(str)

local_people = pd.merge(local, code, how='inner',left_on='행정동코드', right_on='행자부행정동코드')
local_people
?"기준일ID" 시간대구분 행정동코드 집계구코드 총생활인구수 남자0세부터9세생활인구수 남자10세부터14세생활인구수 남자15세부터19세생활인구수 남자20세부터24세생활인구수 남자25세부터29세생활인구수 ... 여자50세부터54세생활인구수 여자55세부터59세생활인구수 여자60세부터64세생활인구수 여자65세부터69세생활인구수 여자70세이상생활인구수 통계청행정동코드 행자부행정동코드 시도명 시군구명 행정동명
0 20200513 8 11110560 1101056030003 35.3457 * * * * * ... * * * * * 1101056 11110560 서울 종로구 평창동
1 20200513 15 11110560 1101056030003 37.6209 * * * * * ... * * * * * 1101056 11110560 서울 종로구 평창동
2 20200513 3 11110560 1101056010001 1008.4026 29.506 21.3427 36.3295 26.9718 28.6688 ... 53.5057 40.7928 34.237 17.7718 114.2034 1101056 11110560 서울 종로구 평창동
3 20200513 10 11110560 1101056010001 792.4054 11.0166 7.9686 31.5255 31.5578 23.5806 ... 40.9175 35.8251 42.0529 25.5369 102.4189 1101056 11110560 서울 종로구 평창동
4 20200513 17 11110560 1101056010001 759.8254 29.0181 20.9898 19.9353 37.4775 16.826 ... 28.6201 45.2668 30.4154 29.5657 67.8588 1101056 11110560 서울 종로구 평창동
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
459647 20200513 10 11740700 1125071022701 140.6605 8.22 4.1466 6.1204 7.0038 * ... 5.6079 * 8.7991 4.4082 11.6574 1125071 11740700 서울 강동구 둔촌2동
459648 20200513 17 11740700 1125071022701 131.8683 5.861 * 5.1135 6.3122 * ... 7.5527 5.5306 5.5181 6.8579 5.2525 1125071 11740700 서울 강동구 둔촌2동
459649 20200513 6 11740700 1125071023701 519.4448 14.5584 7.344 17.7149 13.6748 23.8371 ... 24.4111 29.1188 13.2756 11.1782 40.81 1125071 11740700 서울 강동구 둔촌2동
459650 20200513 13 11740700 1125071023701 251.7987 11.8529 5.9792 11.1546 4.6372 5.7058 ... 11.2115 12.5637 10.8003 6.2 19.2498 1125071 11740700 서울 강동구 둔촌2동
459651 20200513 20 11740700 1125071023701 398.0623 12.9668 6.5411 10.1468 * 8.1196 ... 17.5076 17.2666 13.3851 18.0771 31.7392 1125071 11740700 서울 강동구 둔촌2동

459652 rows × 38 columns

앞서 좌표변환을 하여 얻은 geojson파일이다.

h_state_geo = 'shp_to_hang.geojson'
h_cen_str=json.load(open(h_state_geo, encoding='utf-8'))
h_cen_str
{'type': 'FeatureCollection',
 'crs': {'type': 'name',
  'properties': {'name': 'urn:ogc:def:crs:OGC:1.3:CRS84'}},
 'features': [{'type': 'Feature',
   'properties': {'SIDO_CD': '11',
    'SIDO_NM': '서울특별시',
    'SIGUNGU_CD': '11010',
    'SIGUNGU_NM': '종로구',
    'ADM_CD': '1101053',
    'ADM_NM': '사직동'},
   'geometry': {'type': 'Polygon',
    'coordinates': [[[126.9739856237627, 37.578232670039334],
      [126.97400109428702, 37.57809159828244],
      [126.97401404297496, 37.5779712471175],
      [126.9740258913333, 37.57786305830101],
      [126.97404025802075, 37.577735275548],
      [126.97405226331932, 37.57763245673554],
      [126.97405668181658, 37.57759228364722],
      [126.97406550448336, 37.577519124730294],
      [126.97406819439277, 37.57749510505484],
      [126.97406829876296, 37.57749250333688],
      [126.9740683448981, 37.57749109654291],
      [126.9741527610664, 37.577492521780584],
      [126.97415313265654, 37.5774963685736],
      [126.97414136442961, 37.577607691743715] 
      ....]}}]}

geopandas (2) 좌표변환에서 알려준 방식으로 GeoDataFrame형식으로도 불러온다. (hang은 to_crs를 통해 좌표를 변환한 테이블임)

h_cen_str_df= GeoDataFrame(hang, crs='EPSG:4326', geometry='geometry')

시각화에 필요한 부분을 원하는 경우 (3) point로 바로 넘어가세요

(2) 생활인구데이터(local_people)에 위치 연결시키기

이번에는 좌표변환해준 geojson과 생활인구 데이터를 Merge시켜주는 작업을 진행한다. 생활인구 데이터 (local_people)에 통계청행정동코드를 이용하여 위치 merge를 진행한다. 이것도 앞서 언급했던 것처럼, astype()을 이용하여 int에서 str로 변환해준다. 이 부분은 시각화와 크게 관련이 없지만, 미래에 쓰일 수 있기 때문에 진행한 작업이다.

local_people['통계청행정동코드']=local_people['통계청행정동코드'].astype(str)
h_cen_str_df['ADM_CD']=h_cen_str_df['ADM_CD'].astype(str)
h_geo_local = pd.merge(local_people, h_cen_str_df,how='inner', left_on='통계청행정동코드',  right_on='ADM_CD')
h_geo_local
?"기준일ID" 시간대구분 행정동코드 집계구코드 총생활인구수 남자0세부터9세생활인구수 남자10세부터14세생활인구수 남자15세부터19세생활인구수 남자20세부터24세생활인구수 남자25세부터29세생활인구수 ... 시도명 시군구명 행정동명 SIDO_CD SIDO_NM SIGUNGU_CD SIGUNGU_NM ADM_CD ADM_NM geometry
0 20200513 8 11110560 1101056030003 35.3457 * * * * * ... 서울 종로구 평창동 11 서울특별시 11010 종로구 1101056 평창동 POLYGON ((126.97508 37.63118, 126.97468 37.629...
1 20200513 15 11110560 1101056030003 37.6209 * * * * * ... 서울 종로구 평창동 11 서울특별시 11010 종로구 1101056 평창동 POLYGON ((126.97508 37.63118, 126.97468 37.629...
2 20200513 3 11110560 1101056010001 1008.4026 29.506 21.3427 36.3295 26.9718 28.6688 ... 서울 종로구 평창동 11 서울특별시 11010 종로구 1101056 평창동 POLYGON ((126.97508 37.63118, 126.97468 37.629...
3 20200513 10 11110560 1101056010001 792.4054 11.0166 7.9686 31.5255 31.5578 23.5806 ... 서울 종로구 평창동 11 서울특별시 11010 종로구 1101056 평창동 POLYGON ((126.97508 37.63118, 126.97468 37.629...
4 20200513 17 11110560 1101056010001 759.8254 29.0181 20.9898 19.9353 37.4775 16.826 ... 서울 종로구 평창동 11 서울특별시 11010 종로구 1101056 평창동 POLYGON ((126.97508 37.63118, 126.97468 37.629...
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
459647 20200513 10 11740700 1125071022701 140.6605 8.22 4.1466 6.1204 7.0038 * ... 서울 강동구 둔촌2동 11 서울특별시 11250 강동구 1125071 둔촌2동 POLYGON ((127.15671 37.53758, 127.15654 37.537...
459648 20200513 17 11740700 1125071022701 131.8683 5.861 * 5.1135 6.3122 * ... 서울 강동구 둔촌2동 11 서울특별시 11250 강동구 1125071 둔촌2동 POLYGON ((127.15671 37.53758, 127.15654 37.537...
459649 20200513 6 11740700 1125071023701 519.4448 14.5584 7.344 17.7149 13.6748 23.8371 ... 서울 강동구 둔촌2동 11 서울특별시 11250 강동구 1125071 둔촌2동 POLYGON ((127.15671 37.53758, 127.15654 37.537...
459650 20200513 13 11740700 1125071023701 251.7987 11.8529 5.9792 11.1546 4.6372 5.7058 ... 서울 강동구 둔촌2동 11 서울특별시 11250 강동구 1125071 둔촌2동 POLYGON ((127.15671 37.53758, 127.15654 37.537...
459651 20200513 20 11740700 1125071023701 398.0623 12.9668 6.5411 10.1468 * 8.1196 ... 서울 강동구 둔촌2동 11 서울특별시 11250 강동구 1125071 둔촌2동 POLYGON ((127.15671 37.53758, 127.15654 37.537...

459652 rows × 45 columns

행정동 이름에 맞게 위치(위도, 경도)가 잘 붙여진 것을 볼 수 있다. 혹시나 위치가 안붙은게 있나 확인하는 작업을 해주기 위해서 넣은 코드이다.

h_geo_local[h_geo_local['ADM_CD'].isna()]
?"기준일ID" 시간대구분 행정동코드 집계구코드 총생활인구수 남자0세부터9세생활인구수 남자10세부터14세생활인구수 남자15세부터19세생활인구수 남자20세부터24세생활인구수 남자25세부터29세생활인구수 ... 시도명 시군구명 행정동명 SIDO_CD SIDO_NM SIGUNGU_CD SIGUNGU_NM ADM_CD ADM_NM geometry

0 rows × 45 columns

(3) point: 시각화를 위한 전처리

다음으로 진행하는 작업은 시각화에 표현을 하기위해 정리해주는 것이다. 밑 코드 결과를 보면 같은 행정동코드에 시간대가 0~23시까지 다양하다는 것을 알 수 있다. 그래서 이들의 평균을 해준다.

h_geo_local[h_geo_local['행정동코드']=='11710631'].sort_values(by=["시간대구분"])
?"기준일ID" 시간대구분 행정동코드 집계구코드 총생활인구수 남자0세부터9세생활인구수 남자10세부터14세생활인구수 남자15세부터19세생활인구수 남자20세부터24세생활인구수 남자25세부터29세생활인구수 ... 시도명 시군구명 행정동명 SIDO_CD SIDO_NM SIGUNGU_CD SIGUNGU_NM ADM_CD ADM_NM geometry
431413 20200513 0 11710631 1124066010201 29261.1567 982.9456 491.4728 586.949 638.7281 795.332 ... 서울 송파구 가락1동 11 서울특별시 11240 송파구 1124066 가락1동 POLYGON ((127.11015 37.50051, 127.11074 37.499...
431417 20200513 1 11710631 1124066010201 29472.2889 938.0777 469.0388 605.032 635.7256 843.0542 ... 서울 송파구 가락1동 11 서울특별시 11240 송파구 1124066 가락1동 POLYGON ((127.11015 37.50051, 127.11074 37.499...
431421 20200513 2 11710631 1124066010201 29267.7051 978.5644 489.2822 617.5087 638.282 826.8054 ... 서울 송파구 가락1동 11 서울특별시 11240 송파구 1124066 가락1동 POLYGON ((127.11015 37.50051, 127.11074 37.499...
431425 20200513 3 11710631 1124066010201 29190.9486 976.6144 488.3072 589.9348 632.9282 816.6283 ... 서울 송파구 가락1동 11 서울특별시 11240 송파구 1124066 가락1동 POLYGON ((127.11015 37.50051, 127.11074 37.499...
431404 20200513 4 11710631 1124066010201 29409.3125 1000.6028 500.3014 600.3267 644.9461 821.1669 ... 서울 송파구 가락1동 11 서울특별시 11240 송파구 1124066 가락1동 POLYGON ((127.11015 37.50051, 127.11074 37.499...
431410 20200513 5 11710631 1124066010201 29872.2961 994.8333 497.4167 612.4037 631.6917 824.4675 ... 서울 송파구 가락1동 11 서울특별시 11240 송파구 1124066 가락1동 POLYGON ((127.11015 37.50051, 127.11074 37.499...
431407 20200513 6 11710631 1124066010201 30449.8086 968.8595 484.4298 634.3023 679.1918 861.1436 ... 서울 송파구 가락1동 11 서울특별시 11240 송파구 1124066 가락1동 POLYGON ((127.11015 37.50051, 127.11074 37.499...
431414 20200513 7 11710631 1124066010201 30764.6349 1014.8134 507.4067 627.5145 742.4564 818.8834 ... 서울 송파구 가락1동 11 서울특별시 11240 송파구 1124066 가락1동 POLYGON ((127.11015 37.50051, 127.11074 37.499...
431418 20200513 8 11710631 1124066010201 29694.3545 1008.3774 504.1887 621.0838 717.9852 815.5838 ... 서울 송파구 가락1동 11 서울특별시 11240 송파구 1124066 가락1동 POLYGON ((127.11015 37.50051, 127.11074 37.499...
431422 20200513 9 11710631 1124066010201 28589.2626 1057.7848 528.8924 638.4586 677.7513 753.7369 ... 서울 송파구 가락1동 11 서울특별시 11240 송파구 1124066 가락1동 POLYGON ((127.11015 37.50051, 127.11074 37.499...
431426 20200513 10 11710631 1124066010201 27871.1314 1058.7308 529.3654 630.9889 701.4308 733.5563 ... 서울 송파구 가락1동 11 서울특별시 11240 송파구 1124066 가락1동 POLYGON ((127.11015 37.50051, 127.11074 37.499...
431405 20200513 11 11710631 1124066010201 26594.8280 1042.8765 521.4383 630.605 682.089 688.9904 ... 서울 송파구 가락1동 11 서울특별시 11240 송파구 1124066 가락1동 POLYGON ((127.11015 37.50051, 127.11074 37.499...
431411 20200513 12 11710631 1124066010201 25519.5173 974.1138 487.0569 587.2525 653.4448 655.1081 ... 서울 송파구 가락1동 11 서울특별시 11240 송파구 1124066 가락1동 POLYGON ((127.11015 37.50051, 127.11074 37.499...
431408 20200513 13 11710631 1124066010201 25836.1763 995.703 497.8515 567.5561 648.7952 675.6266 ... 서울 송파구 가락1동 11 서울특별시 11240 송파구 1124066 가락1동 POLYGON ((127.11015 37.50051, 127.11074 37.499...
431415 20200513 14 11710631 1124066010201 25612.1681 970.953 485.4765 564.8113 616.906 670.9117 ... 서울 송파구 가락1동 11 서울특별시 11240 송파구 1124066 가락1동 POLYGON ((127.11015 37.50051, 127.11074 37.499...
431419 20200513 15 11710631 1124066010201 25691.4110 1005.9315 502.9658 523.856 620.6962 662.2305 ... 서울 송파구 가락1동 11 서울특별시 11240 송파구 1124066 가락1동 POLYGON ((127.11015 37.50051, 127.11074 37.499...
431423 20200513 16 11710631 1124066010201 25567.3587 919.0554 459.5277 547.3936 614.9056 661.841 ... 서울 송파구 가락1동 11 서울특별시 11240 송파구 1124066 가락1동 POLYGON ((127.11015 37.50051, 127.11074 37.499...
431427 20200513 17 11710631 1124066010201 25795.5094 826.8855 413.4428 502.0771 611.0326 693.194 ... 서울 송파구 가락1동 11 서울특별시 11240 송파구 1124066 가락1동 POLYGON ((127.11015 37.50051, 127.11074 37.499...
431406 20200513 18 11710631 1124066010201 27201.2404 891.1131 445.5566 479.092 619.6159 758.3916 ... 서울 송파구 가락1동 11 서울특별시 11240 송파구 1124066 가락1동 POLYGON ((127.11015 37.50051, 127.11074 37.499...
431412 20200513 19 11710631 1124066010201 27959.5327 930.8949 465.4474 480.9509 607.2719 775.6853 ... 서울 송파구 가락1동 11 서울특별시 11240 송파구 1124066 가락1동 POLYGON ((127.11015 37.50051, 127.11074 37.499...
431409 20200513 20 11710631 1124066010201 28518.1618 857.7065 428.8533 456.7039 571.5066 819.1614 ... 서울 송파구 가락1동 11 서울특별시 11240 송파구 1124066 가락1동 POLYGON ((127.11015 37.50051, 127.11074 37.499...
431416 20200513 21 11710631 1124066010201 29280.4660 908.3874 454.1937 488.0825 615.293 850.9114 ... 서울 송파구 가락1동 11 서울특별시 11240 송파구 1124066 가락1동 POLYGON ((127.11015 37.50051, 127.11074 37.499...
431420 20200513 22 11710631 1124066010201 29682.5222 1024.5873 512.2937 560.1995 581.1035 889.6869 ... 서울 송파구 가락1동 11 서울특별시 11240 송파구 1124066 가락1동 POLYGON ((127.11015 37.50051, 127.11074 37.499...
431424 20200513 23 11710631 1124066010201 29925.1700 1018.9808 509.4904 633.8475 612.5628 839.46 ... 서울 송파구 가락1동 11 서울특별시 11240 송파구 1124066 가락1동 POLYGON ((127.11015 37.50051, 127.11074 37.499...

24 rows × 45 columns

(4) 각 행정동별 값 하나 : 총생활인구수 평균내기

h_nbh_count_df=local_people[["통계청행정동코드","행정동명","총생활인구수"]].groupby(['통계청행정동코드',"행정동명"],as_index=False).mean()
h_nbh_count_df
통계청행정동코드 행정동명 총생활인구수
0 1101053 사직동 1670.201620
1 1101054 삼청동 1225.876593
2 1101055 부암동 762.064492
3 1101056 평창동 504.943168
4 1101057 무악동 449.202430
... ... ... ...
419 1125070 둔촌1동 190.434284
420 1125071 둔촌2동 526.593601
421 1125072 암사1동 388.039118
422 1125073 천호2동 736.710283
423 1125074 길동 542.493326

424 rows × 3 columns

여기서 주의할 점

  • 현재 서울시 행정동은 425개이지만(오류2동이 항동과 오류2동으로 나눠짐),
  • 2020년 데이터에서 항동이 존재하지 않아 424개
  • 서울에 424 개의 행정동이 존재함을 알 수 있다. 즉, 현재 데이터는 2020년이기 때문에 오류2동만 존대한다.

새롭게 만든 변수와 geojson의 Merge를 통해 시각화에 적합한 형태가 완성되었다.

h_nbh_geo_count_df = pd.merge(h_nbh_count_df, h_cen_str_df,how='inner', left_on='통계청행정동코드',  right_on='ADM_CD')
h_nbh_geo_count_df
통계청행정동코드 행정동명 총생활인구수 SIDO_CD SIDO_NM SIGUNGU_CD SIGUNGU_NM ADM_CD ADM_NM geometry
0 1101053 사직동 1670.201620 11 서울특별시 11010 종로구 1101053 사직동 POLYGON ((126.97399 37.57823, 126.97400 37.578...
1 1101054 삼청동 1225.876593 11 서울특별시 11010 종로구 1101054 삼청동 POLYGON ((126.97714 37.59768, 126.97730 37.597...
2 1101055 부암동 762.064492 11 서울특별시 11010 종로구 1101055 부암동 POLYGON ((126.96253 37.60575, 126.96246 37.605...
3 1101056 평창동 504.943168 11 서울특별시 11010 종로구 1101056 평창동 POLYGON ((126.97508 37.63118, 126.97468 37.629...
4 1101057 무악동 449.202430 11 서울특별시 11010 종로구 1101057 무악동 POLYGON ((126.96079 37.57378, 126.96074 37.573...
... ... ... ... ... ... ... ... ... ... ...
419 1125070 둔촌1동 190.434284 11 서울특별시 11250 강동구 1125070 둔촌1동 POLYGON ((127.14480 37.51939, 127.14483 37.519...
420 1125071 둔촌2동 526.593601 11 서울특별시 11250 강동구 1125071 둔촌2동 POLYGON ((127.15671 37.53758, 127.15654 37.537...
421 1125072 암사1동 388.039118 11 서울특별시 11250 강동구 1125072 암사1동 POLYGON ((127.13522 37.55473, 127.13569 37.554...
422 1125073 천호2동 736.710283 11 서울특별시 11250 강동구 1125073 천호2동 POLYGON ((127.11633 37.55005, 127.11642 37.550...
423 1125074 길동 542.493326 11 서울특별시 11250 강동구 1125074 길동 POLYGON ((127.14850 37.54578, 127.14843 37.545...

424 rows × 10 columns

후에 올릴 예정인 ‘mapbox 패키지를 이용한 시각화’를 위한 geojson 파일의 저장이다. geojson에는 총생활인구수가 추가된 것이다.

to_geo_hang= GeoDataFrame(h_nbh_geo_count_df, crs='EPSG:4326', geometry='geometry') 
to_geo_hang.to_file('shp_행정구.geojson', driver='GeoJSON')

이제 시각화를 위한 전처리를 진행했으므로 시각화관련 내용이 이어진다.

댓글남기기